Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into upstream-merge-26492
This commit is contained in:
@@ -45,9 +45,9 @@ INITIALIZE_IMMEDIATE(/obj/effect/statclick)
|
||||
switch(controller)
|
||||
if("Master")
|
||||
Recreate_MC()
|
||||
feedback_add_details("admin_verb","Restart Master Controller")
|
||||
SSblackbox.add_details("admin_verb","Restart Master Controller")
|
||||
if("Failsafe")
|
||||
new /datum/controller/failsafe()
|
||||
feedback_add_details("admin_verb","Restart Failsafe Controller")
|
||||
SSblackbox.add_details("admin_verb","Restart Failsafe Controller")
|
||||
|
||||
message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
|
||||
|
||||
@@ -43,10 +43,8 @@
|
||||
var/log_attack = 0 // log attack messages
|
||||
var/log_adminchat = 0 // log admin chat messages
|
||||
var/log_pda = 0 // log pda messages
|
||||
var/log_hrefs = 0 // log all links clicked in-game. Could be used for debugging and tracking down exploits
|
||||
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/log_runtimes = FALSE // log runtimes into a file
|
||||
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
|
||||
@@ -66,9 +64,9 @@
|
||||
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/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.
|
||||
@@ -129,6 +127,7 @@
|
||||
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?
|
||||
|
||||
var/traitor_scaling_coeff = 6 //how much does the amount of players get divided by to determine traitors
|
||||
@@ -269,7 +268,7 @@
|
||||
|
||||
if(M.config_tag)
|
||||
if(!(M.config_tag in modes)) // ensure each mode is added only once
|
||||
GLOB.diary << "Adding game mode [M.name] ([M.config_tag]) to configuration."
|
||||
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
|
||||
@@ -291,7 +290,7 @@
|
||||
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
|
||||
var/list/Lines = world.file2list(filename)
|
||||
var/list/Lines = world.file2list(filename)
|
||||
|
||||
for(var/t in Lines)
|
||||
if(!t)
|
||||
@@ -358,8 +357,6 @@
|
||||
log_adminchat = 1
|
||||
if("log_pda")
|
||||
log_pda = 1
|
||||
if("log_hrefs")
|
||||
log_hrefs = 1
|
||||
if("log_twitter")
|
||||
log_twitter = 1
|
||||
if("log_world_topic")
|
||||
@@ -410,12 +407,12 @@
|
||||
usewhitelist = TRUE
|
||||
if("allow_metadata")
|
||||
allow_Metadata = 1
|
||||
if("inactivity_period")
|
||||
inactivity_period = text2num(value) * 10 //documented as seconds in config.txt
|
||||
if("afk_period")
|
||||
afk_period = text2num(value) * 10 // ^^^
|
||||
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
|
||||
kick_inactive = TRUE
|
||||
if("load_jobs_from_txt")
|
||||
load_jobs_from_txt = 1
|
||||
if("forbid_singulo_possession")
|
||||
@@ -476,6 +473,8 @@
|
||||
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")
|
||||
@@ -493,12 +492,6 @@
|
||||
ipintel_save_bad = text2num(value)
|
||||
if("aggressive_changelog")
|
||||
aggressive_changelog = 1
|
||||
if("log_runtimes")
|
||||
log_runtimes = TRUE
|
||||
var/newlog = file("data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log")
|
||||
if(GLOB.runtime_diary != newlog)
|
||||
world.log << "Now logging runtimes to data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log"
|
||||
GLOB.runtime_diary = newlog
|
||||
if("autoconvert_notes")
|
||||
autoconvert_notes = 1
|
||||
if("allow_webclient")
|
||||
@@ -542,7 +535,7 @@
|
||||
if("error_msg_delay")
|
||||
error_msg_delay = text2num(value)
|
||||
else
|
||||
GLOB.diary << "Unknown setting in configuration: '[name]'"
|
||||
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
|
||||
|
||||
else if(type == "game_options")
|
||||
switch(name)
|
||||
@@ -605,13 +598,13 @@
|
||||
if(mode_name in modes)
|
||||
continuous[mode_name] = 1
|
||||
else
|
||||
GLOB.diary << "Unknown continuous configuration definition: [mode_name]."
|
||||
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
|
||||
GLOB.diary << "Unknown midround antagonist configuration definition: [mode_name]."
|
||||
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")
|
||||
@@ -627,9 +620,9 @@
|
||||
if(mode_name in modes)
|
||||
min_pop[mode_name] = text2num(mode_value)
|
||||
else
|
||||
GLOB.diary << "Unknown minimum population configuration definition: [mode_name]."
|
||||
GLOB.config_error_log << "Unknown minimum population configuration definition: [mode_name]."
|
||||
else
|
||||
GLOB.diary << "Incorrect minimum population configuration definition: [mode_name] [mode_value]."
|
||||
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
|
||||
@@ -641,9 +634,9 @@
|
||||
if(mode_name in modes)
|
||||
max_pop[mode_name] = text2num(mode_value)
|
||||
else
|
||||
GLOB.diary << "Unknown maximum population configuration definition: [mode_name]."
|
||||
GLOB.config_error_log << "Unknown maximum population configuration definition: [mode_name]."
|
||||
else
|
||||
GLOB.diary << "Incorrect maximum population configuration definition: [mode_name] [mode_value]."
|
||||
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")
|
||||
@@ -671,9 +664,9 @@
|
||||
if(prob_name in modes)
|
||||
probabilities[prob_name] = text2num(prob_value)
|
||||
else
|
||||
GLOB.diary << "Unknown game mode probability configuration definition: [prob_name]."
|
||||
GLOB.config_error_log << "Unknown game mode probability configuration definition: [prob_name]."
|
||||
else
|
||||
GLOB.diary << "Incorrect probability configuration definition: [prob_name] [prob_value]."
|
||||
GLOB.config_error_log << "Incorrect probability configuration definition: [prob_name] [prob_value]."
|
||||
|
||||
if("protect_roles_from_antagonist")
|
||||
protect_roles_from_antagonist = 1
|
||||
@@ -720,7 +713,7 @@
|
||||
// Value is in the form "LAWID,NUMBER"
|
||||
var/list/L = splittext(value, ",")
|
||||
if(L.len != 2)
|
||||
GLOB.diary << "Invalid LAW_WEIGHT: " + t
|
||||
GLOB.config_error_log << "Invalid LAW_WEIGHT: " + t
|
||||
continue
|
||||
var/lawid = L[1]
|
||||
var/weight = text2num(L[2])
|
||||
@@ -776,8 +769,8 @@
|
||||
mentors_mobname_only = 1
|
||||
if ("mentor_legacy_system")
|
||||
mentor_legacy_system = 1
|
||||
else
|
||||
GLOB.diary << "Unknown setting in configuration: '[name]'"
|
||||
// else
|
||||
// GLOB.config_error_log << "Adding game mode [M.name] ([M.config_tag]) to configuration."
|
||||
|
||||
fps = round(fps)
|
||||
if(fps <= 0)
|
||||
@@ -785,7 +778,7 @@
|
||||
|
||||
|
||||
/datum/configuration/proc/loadmaplist(filename)
|
||||
var/list/Lines = world.file2list(filename)
|
||||
var/list/Lines = world.file2list(filename)
|
||||
|
||||
var/datum/map_config/currentmap = null
|
||||
for(var/t in Lines)
|
||||
@@ -831,11 +824,11 @@
|
||||
maplist[currentmap.map_name] = currentmap
|
||||
currentmap = null
|
||||
else
|
||||
GLOB.diary << "Unknown command in map vote config: '[command]'"
|
||||
GLOB.config_error_log << "Unknown command in map vote config: '[command]'"
|
||||
|
||||
|
||||
/datum/configuration/proc/loadsql(filename)
|
||||
var/list/Lines = world.file2list(filename)
|
||||
var/list/Lines = world.file2list(filename)
|
||||
for(var/t in Lines)
|
||||
if(!t)
|
||||
continue
|
||||
@@ -875,7 +868,7 @@
|
||||
if("feedback_tableprefix")
|
||||
global.sqlfdbktableprefix = value
|
||||
else
|
||||
GLOB.diary << "Unknown setting in configuration: '[name]'"
|
||||
GLOB.config_error_log << "Unknown setting in configuration: '[name]'"
|
||||
|
||||
/datum/configuration/proc/pick_mode(mode_name)
|
||||
// I wish I didn't have to instance the game modes in order to look up
|
||||
|
||||
@@ -52,6 +52,12 @@ GLOBAL_REAL(GLOB, /datum/controller/global_vars)
|
||||
/datum/controller/global_vars/Initialize()
|
||||
gvars_datum_init_order = list()
|
||||
gvars_datum_protected_varlist = list("gvars_datum_protected_varlist")
|
||||
|
||||
//See https://github.com/tgstation/tgstation/issues/26954
|
||||
for(var/I in typesof(/datum/controller/global_vars/proc))
|
||||
var/CLEANBOT_RETURNS = "[I]"
|
||||
pass(CLEANBOT_RETURNS)
|
||||
|
||||
for(var/I in vars - gvars_datum_in_built_vars)
|
||||
var/start_tick = world.time
|
||||
call(src, "InitGlobal[I]")()
|
||||
|
||||
+18
-13
@@ -48,7 +48,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
|
||||
var/initializations_finished_with_no_players_logged_in //I wonder what this could be?
|
||||
// Has round started? (So we know what subsystems to run)
|
||||
var/round_started = 0
|
||||
var/local_round_started = FALSE //Don't read this var, use SSticker.HasRoundStarted() instead
|
||||
|
||||
// The type of the last subsystem to be process()'d.
|
||||
var/last_type_processed
|
||||
@@ -189,7 +189,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
|
||||
// Notify the MC that the round has started.
|
||||
/datum/controller/master/proc/RoundStart()
|
||||
round_started = 1
|
||||
local_round_started = TRUE
|
||||
var/timer = world.time
|
||||
for (var/datum/controller/subsystem/SS in subsystems)
|
||||
if (SS.flags & SS_FIRE_IN_LOBBY || SS.flags & SS_TICKER)
|
||||
@@ -222,7 +222,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
// local vars rock
|
||||
|
||||
// Schedule the first run of the Subsystems.
|
||||
round_started = world.has_round_started()
|
||||
local_round_started = world.has_round_started()
|
||||
//all this shit is here so that flag edits can be refreshed by restarting the MC. (and for speed)
|
||||
var/list/tickersubsystems = list()
|
||||
var/list/normalsubsystems = list()
|
||||
@@ -245,7 +245,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
lobbysubsystems += SS
|
||||
timer += world.tick_lag * rand(1, 5)
|
||||
SS.next_fire = timer
|
||||
else if (round_started)
|
||||
else if (local_round_started)
|
||||
timer += world.tick_lag * rand(1, 5)
|
||||
SS.next_fire = timer
|
||||
normalsubsystems += SS
|
||||
@@ -280,7 +280,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
// because sleeps are processed in the order received, so longer sleeps are more likely to run first
|
||||
if (world.tick_usage > TICK_LIMIT_MC)
|
||||
sleep_delta += 2
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING - (TICK_LIMIT_RUNNING * 0.5)
|
||||
GLOB.CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING * 0.5
|
||||
sleep(world.tick_lag * (processing + sleep_delta))
|
||||
continue
|
||||
|
||||
@@ -296,7 +296,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
if (!Failsafe || (Failsafe.processing_interval > 0 && (Failsafe.lasttick+(Failsafe.processing_interval*5)) < world.time))
|
||||
new/datum/controller/failsafe() // (re)Start the failsafe.
|
||||
if (!queue_head || !(iteration % 3))
|
||||
if (round_started)
|
||||
if (local_round_started)
|
||||
subsystems_to_check = normalsubsystems
|
||||
else
|
||||
subsystems_to_check = lobbysubsystems
|
||||
@@ -421,26 +421,31 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
else
|
||||
tick_precentage = tick_remaining
|
||||
|
||||
GLOB.CURRENT_TICKLIMIT = world.tick_usage + tick_precentage
|
||||
tick_precentage = max(tick_precentage*0.5, tick_precentage-queue_node.tick_overrun)
|
||||
|
||||
GLOB.CURRENT_TICKLIMIT = round(world.tick_usage + tick_precentage)
|
||||
|
||||
if (!(queue_node_flags & SS_TICKER))
|
||||
ran_non_ticker = TRUE
|
||||
ran = TRUE
|
||||
tick_usage = world.tick_usage
|
||||
|
||||
queue_node_paused = (queue_node.state == SS_PAUSED || queue_node.state == SS_PAUSING)
|
||||
last_type_processed = queue_node
|
||||
|
||||
queue_node.state = SS_RUNNING
|
||||
|
||||
tick_usage = world.tick_usage
|
||||
var/state = queue_node.ignite(queue_node_paused)
|
||||
tick_usage = world.tick_usage - tick_usage
|
||||
|
||||
if (state == SS_RUNNING)
|
||||
state = SS_IDLE
|
||||
current_tick_budget -= queue_node_priority
|
||||
tick_usage = world.tick_usage - tick_usage
|
||||
|
||||
|
||||
if (tick_usage < 0)
|
||||
tick_usage = 0
|
||||
|
||||
queue_node.tick_overrun = max(0, MC_AVG_FAST_UP_SLOW_DOWN(queue_node.tick_overrun, tick_usage-tick_precentage))
|
||||
queue_node.state = state
|
||||
|
||||
if (state == SS_PAUSED)
|
||||
@@ -467,13 +472,13 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING)
|
||||
queue_node.times_fired++
|
||||
|
||||
if (queue_node_flags & SS_TICKER)
|
||||
queue_node.next_fire = world.time + (world.tick_lag * queue_node.wait)
|
||||
queue_node.next_fire = world.time + (world.tick_lag * (queue_node.wait + (queue_node.tick_overrun/100)))
|
||||
else if (queue_node_flags & SS_POST_FIRE_TIMING)
|
||||
queue_node.next_fire = world.time + queue_node.wait
|
||||
queue_node.next_fire = world.time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100))
|
||||
else if (queue_node_flags & SS_KEEP_TIMING)
|
||||
queue_node.next_fire += queue_node.wait
|
||||
else
|
||||
queue_node.next_fire = queue_node.queued_time + queue_node.wait
|
||||
queue_node.next_fire = queue_node.queued_time + queue_node.wait + (world.tick_lag * (queue_node.tick_overrun/100))
|
||||
|
||||
queue_node.queued_time = 0
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
var/next_fire = 0 //scheduled world.time for next fire()
|
||||
var/cost = 0 //average time to execute
|
||||
var/tick_usage = 0 //average tick usage
|
||||
var/tick_overrun = 0 //average tick overrun
|
||||
var/state = SS_IDLE //tracks the current state of the ss, running, paused, etc.
|
||||
var/paused_ticks = 0 //ticks this ss is taking to run right now.
|
||||
var/paused_tick_usage //total tick_usage of all of our runs while pausing this run
|
||||
@@ -168,7 +169,7 @@
|
||||
|
||||
|
||||
if(can_fire && !(SS_NO_FIRE in flags))
|
||||
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%|[round(ticks,0.1)]\t[msg]"
|
||||
msg = "[round(cost,1)]ms|[round(tick_usage,1)]%([round(tick_overrun,1)]%)|[round(ticks,0.1)]\t[msg]"
|
||||
else
|
||||
msg = "OFFLINE\t[msg]"
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
diff a/code/controllers/subsystem/atoms.dm b/code/controllers/subsystem/atoms.dm (rejected hunks)
|
||||
@@ -12,6 +12,7 @@ SUBSYSTEM_DEF(atoms)
|
||||
var/old_initialized
|
||||
|
||||
var/list/late_loaders
|
||||
+ var/list/created_atoms
|
||||
|
||||
var/list/BadInitializeCalls = list()
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
SUBSYSTEM_DEF(blackbox)
|
||||
name = "Blackbox"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK
|
||||
|
||||
var/list/msg_common = list()
|
||||
var/list/msg_science = list()
|
||||
var/list/msg_command = list()
|
||||
var/list/msg_medical = list()
|
||||
var/list/msg_engineering = list()
|
||||
var/list/msg_security = list()
|
||||
var/list/msg_deathsquad = list()
|
||||
var/list/msg_syndicate = list()
|
||||
var/list/msg_service = list()
|
||||
var/list/msg_cargo = list()
|
||||
var/list/msg_other = list()
|
||||
|
||||
var/list/feedback = list() //list of datum/feedback_variable
|
||||
|
||||
//poll population
|
||||
/datum/controller/subsystem/blackbox/fire()
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
var/playercount = 0
|
||||
for(var/mob/M in GLOB.player_list)
|
||||
if(M.client)
|
||||
playercount += 1
|
||||
var/admincount = GLOB.admins.len
|
||||
var/datum/DBQuery/query_record_playercount = SSdbcore.NewQuery("INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time, server_ip, server_port) VALUES ([playercount], [admincount], '[SQLtime()]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
query_record_playercount.Execute()
|
||||
|
||||
/datum/controller/subsystem/blackbox/Recover()
|
||||
msg_common = SSblackbox.msg_common
|
||||
msg_science = SSblackbox.msg_science
|
||||
msg_command = SSblackbox.msg_command
|
||||
msg_medical = SSblackbox.msg_medical
|
||||
msg_engineering = SSblackbox.msg_engineering
|
||||
msg_security = SSblackbox.msg_security
|
||||
msg_deathsquad = SSblackbox.msg_deathsquad
|
||||
msg_syndicate = SSblackbox.msg_syndicate
|
||||
msg_service = SSblackbox.msg_service
|
||||
msg_cargo = SSblackbox.msg_cargo
|
||||
msg_other = SSblackbox.msg_other
|
||||
|
||||
|
||||
feedback = SSblackbox.feedback
|
||||
|
||||
//no touchie
|
||||
/datum/controller/subsystem/blackbox/can_vv_get(var_name)
|
||||
if(var_name == "feedback")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
/datum/controller/subsystem/blackbox/vv_edit_var(var_name, var_value)
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/blackbox/Shutdown()
|
||||
var/pda_msg_amt = 0
|
||||
var/rc_msg_amt = 0
|
||||
|
||||
for (var/obj/machinery/message_server/MS in GLOB.message_servers)
|
||||
if (MS.pda_msgs.len > pda_msg_amt)
|
||||
pda_msg_amt = MS.pda_msgs.len
|
||||
if (MS.rc_msgs.len > rc_msg_amt)
|
||||
rc_msg_amt = MS.rc_msgs.len
|
||||
|
||||
set_details("radio_usage","")
|
||||
|
||||
add_details("radio_usage","COM-[msg_common.len]")
|
||||
add_details("radio_usage","SCI-[msg_science.len]")
|
||||
add_details("radio_usage","HEA-[msg_command.len]")
|
||||
add_details("radio_usage","MED-[msg_medical.len]")
|
||||
add_details("radio_usage","ENG-[msg_engineering.len]")
|
||||
add_details("radio_usage","SEC-[msg_security.len]")
|
||||
add_details("radio_usage","DTH-[msg_deathsquad.len]")
|
||||
add_details("radio_usage","SYN-[msg_syndicate.len]")
|
||||
add_details("radio_usage","SRV-[msg_service.len]")
|
||||
add_details("radio_usage","CAR-[msg_cargo.len]")
|
||||
add_details("radio_usage","OTH-[msg_other.len]")
|
||||
add_details("radio_usage","PDA-[pda_msg_amt]")
|
||||
add_details("radio_usage","RC-[rc_msg_amt]")
|
||||
|
||||
set_details("round_end","[time2text(world.realtime)]") //This one MUST be the last one that gets set.
|
||||
|
||||
if (!SSdbcore.Connect())
|
||||
return
|
||||
|
||||
var/sqlrowlist = ""
|
||||
|
||||
for (var/datum/feedback_variable/FV in feedback)
|
||||
if (sqlrowlist != "")
|
||||
sqlrowlist += ", " //a comma (,) at the start of the first row to insert will trigger a SQL error
|
||||
|
||||
sqlrowlist += "(null, Now(), [GLOB.round_id], \"[sanitizeSQL(FV.get_variable())]\", [FV.get_value()], \"[sanitizeSQL(FV.get_details())]\")"
|
||||
|
||||
if (sqlrowlist == "")
|
||||
return
|
||||
|
||||
var/datum/DBQuery/query_feedback_save = SSdbcore.NewQuery("INSERT DELAYED IGNORE INTO [format_table_name("feedback")] VALUES " + sqlrowlist)
|
||||
query_feedback_save.Execute()
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/LogBroadcast(blackbox_msg, freq)
|
||||
switch(freq)
|
||||
if(1459)
|
||||
msg_common += blackbox_msg
|
||||
if(1351)
|
||||
msg_science += blackbox_msg
|
||||
if(1353)
|
||||
msg_command += blackbox_msg
|
||||
if(1355)
|
||||
msg_medical += blackbox_msg
|
||||
if(1357)
|
||||
msg_engineering += blackbox_msg
|
||||
if(1359)
|
||||
msg_security += blackbox_msg
|
||||
if(1441)
|
||||
msg_deathsquad += blackbox_msg
|
||||
if(1213)
|
||||
msg_syndicate += blackbox_msg
|
||||
if(1349)
|
||||
msg_service += blackbox_msg
|
||||
if(1347)
|
||||
msg_cargo += blackbox_msg
|
||||
else
|
||||
msg_other += blackbox_msg
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/find_feedback_datum(variable)
|
||||
for(var/datum/feedback_variable/FV in feedback)
|
||||
if(FV.get_variable() == variable)
|
||||
return FV
|
||||
|
||||
var/datum/feedback_variable/FV = new(variable)
|
||||
feedback += FV
|
||||
return FV
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_val(variable, value)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_value(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/inc(variable, value)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.inc(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/dec(variable,value)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.dec(value)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/set_details(variable,details)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.set_details(details)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/add_details(variable,details)
|
||||
var/datum/feedback_variable/FV = find_feedback_datum(variable)
|
||||
FV.add_details(details)
|
||||
|
||||
/datum/controller/subsystem/blackbox/proc/ReportDeath(mob/living/L)
|
||||
if(!SSdbcore.Connect())
|
||||
return
|
||||
if(!L || !L.key || !L.mind)
|
||||
return
|
||||
var/turf/T = get_turf(L)
|
||||
var/area/placeofdeath = get_area(T.loc)
|
||||
var/sqlname = sanitizeSQL(L.real_name)
|
||||
var/sqlkey = sanitizeSQL(L.ckey)
|
||||
var/sqljob = sanitizeSQL(L.mind.assigned_role)
|
||||
var/sqlspecial = sanitizeSQL(L.mind.special_role)
|
||||
var/sqlpod = sanitizeSQL(placeofdeath.name)
|
||||
var/laname
|
||||
var/lakey
|
||||
if(L.lastattacker && ismob(L.lastattacker))
|
||||
var/mob/LA = L.lastattacker
|
||||
laname = sanitizeSQL(LA.real_name)
|
||||
lakey = sanitizeSQL(LA.key)
|
||||
var/sqlgender = sanitizeSQL(L.gender)
|
||||
var/sqlbrute = sanitizeSQL(L.getBruteLoss())
|
||||
var/sqlfire = sanitizeSQL(L.getFireLoss())
|
||||
var/sqlbrain = sanitizeSQL(L.getBrainLoss())
|
||||
var/sqloxy = sanitizeSQL(L.getOxyLoss())
|
||||
var/sqltox = sanitizeSQL(L.getStaminaLoss())
|
||||
var/sqlclone = sanitizeSQL(L.getStaminaLoss())
|
||||
var/sqlstamina = sanitizeSQL(L.getStaminaLoss())
|
||||
var/coord = sanitizeSQL("[L.x], [L.y], [L.z]")
|
||||
var/map = sanitizeSQL(SSmapping.config.map_name)
|
||||
var/datum/DBQuery/query_report_death = SSdbcore.NewQuery("INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, toxloss, cloneloss, staminaloss, coord, mapname, server_ip, server_port) VALUES ('[sqlname]', '[sqlkey]', '[sqljob]', '[sqlspecial]', '[sqlpod]', '[SQLtime()]', '[laname]', '[lakey]', '[sqlgender]', [sqlbrute], [sqlfire], [sqlbrain], [sqloxy], [sqltox], [sqlclone], [sqlstamina], '[coord]', '[map]', INET_ATON('[world.internet_address]'), '[world.port]')")
|
||||
query_report_death.Execute()
|
||||
|
||||
|
||||
//feedback variable datum, for storing all kinds of data
|
||||
/datum/feedback_variable
|
||||
var/variable
|
||||
var/value
|
||||
var/details
|
||||
|
||||
/datum/feedback_variable/New(param_variable, param_value = 0)
|
||||
variable = param_variable
|
||||
value = param_value
|
||||
|
||||
/datum/feedback_variable/proc/inc(num = 1)
|
||||
if (isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = text2num(value)
|
||||
if (isnum(value))
|
||||
value += num
|
||||
else
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/dec(num = 1)
|
||||
if (isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = text2num(value)
|
||||
if (isnum(value))
|
||||
value -= num
|
||||
else
|
||||
value = -num
|
||||
|
||||
/datum/feedback_variable/proc/set_value(num)
|
||||
if (isnum(num))
|
||||
value = num
|
||||
|
||||
/datum/feedback_variable/proc/get_value()
|
||||
if (!isnum(value))
|
||||
return 0
|
||||
return value
|
||||
|
||||
/datum/feedback_variable/proc/get_variable()
|
||||
return variable
|
||||
|
||||
/datum/feedback_variable/proc/set_details(text)
|
||||
if (istext(text))
|
||||
details = text
|
||||
|
||||
/datum/feedback_variable/proc/add_details(text)
|
||||
if (istext(text))
|
||||
text = replacetext(text, " ", "_")
|
||||
if (!details)
|
||||
details = text
|
||||
else
|
||||
details += " [text]"
|
||||
|
||||
/datum/feedback_variable/proc/get_details()
|
||||
return details
|
||||
|
||||
/datum/feedback_variable/proc/get_parsed()
|
||||
return list(variable,value,details)
|
||||
@@ -308,7 +308,6 @@ SUBSYSTEM_DEF(job)
|
||||
Debug("DO non-human failed, Player: [player], Job:[job.title]")
|
||||
continue
|
||||
|
||||
|
||||
// If the player wants that job on this level, then try give it to him.
|
||||
if(player.client.prefs.GetJobDepartment(job, level) & job.flag)
|
||||
|
||||
@@ -319,6 +318,7 @@ SUBSYSTEM_DEF(job)
|
||||
unassigned -= player
|
||||
break
|
||||
|
||||
|
||||
// Hand out random jobs to the people who didn't get any in the last check
|
||||
// Also makes sure that they got their preference correct
|
||||
for(var/mob/dead/new_player/player in unassigned)
|
||||
@@ -483,7 +483,7 @@ SUBSYSTEM_DEF(job)
|
||||
else level4++ //not selected
|
||||
|
||||
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
|
||||
feedback_add_details("job_preferences",tmp_str)
|
||||
SSblackbox.add_details("job_preferences",tmp_str)
|
||||
|
||||
/datum/controller/subsystem/job/proc/PopcapReached()
|
||||
if(config.hard_popcap || config.extreme_popcap)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
SUBSYSTEM_DEF(language)
|
||||
name = "Language"
|
||||
init_order = INIT_ORDER_LANGUAGE
|
||||
flags = SS_NO_FIRE
|
||||
|
||||
/datum/controller/subsystem/language/Initialize(timeofday)
|
||||
for(var/L in subtypesof(/datum/language))
|
||||
var/datum/language/language = L
|
||||
if(!initial(language.key))
|
||||
continue
|
||||
|
||||
GLOB.all_languages += language
|
||||
|
||||
var/datum/language/instance = new language
|
||||
|
||||
GLOB.language_datum_instances[language] = instance
|
||||
|
||||
return ..()
|
||||
@@ -36,18 +36,10 @@ SUBSYSTEM_DEF(lighting)
|
||||
for (i in 1 to GLOB.lighting_update_lights.len)
|
||||
var/datum/light_source/L = GLOB.lighting_update_lights[i]
|
||||
|
||||
if (L.check() || QDELETED(L) || L.force_update)
|
||||
L.remove_lum()
|
||||
if (!QDELETED(L))
|
||||
L.apply_lum()
|
||||
L.update_corners()
|
||||
|
||||
else if (L.vis_update) //We smartly update only tiles that became (in) visible to use.
|
||||
L.smart_vis_update()
|
||||
L.needs_update = LIGHTING_NO_UPDATE
|
||||
|
||||
L.vis_update = FALSE
|
||||
L.force_update = FALSE
|
||||
L.needs_update = FALSE
|
||||
|
||||
if(init_tick_checks)
|
||||
CHECK_TICK
|
||||
else if (MC_TICK_CHECK)
|
||||
|
||||
@@ -119,7 +119,7 @@ SUBSYSTEM_DEF(mapping)
|
||||
INIT_ANNOUNCE("Loading [config.map_name]...")
|
||||
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
|
||||
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
|
||||
feedback_add_details("map_name", config.map_name)
|
||||
SSblackbox.add_details("map_name", config.map_name)
|
||||
|
||||
if(config.minetype != "lavaland")
|
||||
INIT_ANNOUNCE("WARNING: A map without lavaland set as it's minetype was loaded! This is being ignored! Update the maploader code!")
|
||||
|
||||
@@ -150,7 +150,7 @@ SUBSYSTEM_DEF(pai)
|
||||
if(!(ROLE_PAI in G.client.prefs.be_special))
|
||||
continue
|
||||
//G << 'sound/misc/server-ready.ogg' //Alerting them to their consideration
|
||||
to_chat(G, "<span class='ghostalert'>Someone is requesting a pAI personality! Use the pAI button to submit yourself as one.</span>")
|
||||
to_chat(G, "<span class='ghostalert'>[user] is requesting a pAI personality! Use the pAI button to submit yourself as one.</span>")
|
||||
addtimer(CALLBACK(src, .proc/spam_again), spam_delay)
|
||||
var/list/available = list()
|
||||
for(var/datum/paiCandidate/c in SSpai.candidates)
|
||||
|
||||
@@ -9,12 +9,15 @@ SUBSYSTEM_DEF(persistence)
|
||||
|
||||
var/list/obj/structure/chisel_message/chisel_messages = list()
|
||||
var/list/saved_messages = list()
|
||||
var/savefile/chisel_messages_sav
|
||||
|
||||
var/savefile/trophy_sav
|
||||
var/list/saved_trophies = list()
|
||||
|
||||
/datum/controller/subsystem/persistence/Initialize()
|
||||
LoadSatchels()
|
||||
LoadPoly()
|
||||
LoadChiselMessages()
|
||||
LoadTrophies()
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadSatchels()
|
||||
@@ -71,14 +74,14 @@ SUBSYSTEM_DEF(persistence)
|
||||
break //Who's been duping the bird?!
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
|
||||
chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
var/saved_json
|
||||
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
|
||||
|
||||
if(!saved_json)
|
||||
return
|
||||
|
||||
var/saved_messages = json_decode(saved_json)
|
||||
var/list/saved_messages = json_decode(saved_json)
|
||||
|
||||
for(var/item in saved_messages)
|
||||
if(!islist(item))
|
||||
@@ -100,15 +103,57 @@ SUBSYSTEM_DEF(persistence)
|
||||
|
||||
var/obj/structure/chisel_message/M = new(T)
|
||||
|
||||
M.unpack(item)
|
||||
if(!M.loc)
|
||||
M.persists = FALSE
|
||||
qdel(M)
|
||||
if(!QDELETED(M))
|
||||
M.unpack(item)
|
||||
|
||||
log_world("Loaded [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/LoadTrophies()
|
||||
trophy_sav = new /savefile("data/npc_saves/TrophyItems.sav")
|
||||
var/saved_json
|
||||
trophy_sav >> saved_json
|
||||
|
||||
if(!saved_json)
|
||||
return
|
||||
|
||||
var/decoded_json = json_decode(saved_json)
|
||||
|
||||
if(!islist(decoded_json))
|
||||
return
|
||||
|
||||
saved_trophies = decoded_json
|
||||
|
||||
SetUpTrophies(saved_trophies.Copy())
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SetUpTrophies(list/trophy_items)
|
||||
for(var/A in GLOB.trophy_cases)
|
||||
var/obj/structure/displaycase/trophy/T = A
|
||||
T.added_roundstart = TRUE
|
||||
|
||||
var/trophy_data = pick_n_take(trophy_items)
|
||||
|
||||
if(!islist(trophy_data))
|
||||
continue
|
||||
|
||||
var/list/chosen_trophy = trophy_data
|
||||
|
||||
if(!chosen_trophy || isemptylist(chosen_trophy)) //Malformed
|
||||
continue
|
||||
|
||||
var/path = text2path(chosen_trophy["path"]) //If the item no longer exist, this returns null
|
||||
if(!path)
|
||||
continue
|
||||
|
||||
T.showpiece = new /obj/item/showpiece_dummy(T, path)
|
||||
T.trophy_message = chosen_trophy["message"]
|
||||
T.placer_key = chosen_trophy["placer_key"]
|
||||
T.update_icon()
|
||||
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectData()
|
||||
CollectChiselMessages()
|
||||
CollectSecretSatchels()
|
||||
CollectTrophies()
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
|
||||
for(var/A in new_secret_satchels)
|
||||
@@ -129,10 +174,26 @@ SUBSYSTEM_DEF(persistence)
|
||||
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
|
||||
var/savefile/chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
|
||||
|
||||
for(var/obj/structure/chisel_message/M in chisel_messages)
|
||||
saved_messages += list(M.pack())
|
||||
|
||||
log_world("Saved [saved_messages.len] engraved messages on map [SSmapping.config.map_name]")
|
||||
|
||||
chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
|
||||
saved_messages += list(M.pack()) // dm eats one list.
|
||||
saved_messages += list(M.pack()) // dm eats one list
|
||||
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/CollectTrophies()
|
||||
trophy_sav << json_encode(saved_trophies)
|
||||
|
||||
/datum/controller/subsystem/persistence/proc/SaveTrophy(obj/structure/displaycase/trophy/T)
|
||||
if(!T.added_roundstart && T.showpiece)
|
||||
var/list/data = list()
|
||||
data["path"] = T.showpiece.type
|
||||
data["message"] = T.trophy_message
|
||||
data["placer_key"] = T.placer_key
|
||||
saved_trophies += list(data)
|
||||
|
||||
@@ -3,14 +3,20 @@
|
||||
SUBSYSTEM_DEF(ping)
|
||||
name = "Ping"
|
||||
wait = 6
|
||||
flags = SS_NO_INIT|SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
|
||||
flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
|
||||
priority = 10
|
||||
var/list/currentrun
|
||||
|
||||
/datum/controller/subsystem/ping/Initialize()
|
||||
if (config.hub)
|
||||
world.visibility = 1
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/ping/fire(resumed = FALSE)
|
||||
if (!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
var/round_started = Master.round_started
|
||||
var/list/currentrun = src.currentrun
|
||||
while (length(currentrun))
|
||||
var/client/C = currentrun[currentrun.len]
|
||||
@@ -19,7 +25,15 @@ SUBSYSTEM_DEF(ping)
|
||||
if (MC_TICK_CHECK)
|
||||
return
|
||||
continue
|
||||
|
||||
if(round_started && C.is_afk(INACTIVITY_KICK))
|
||||
if(!istype(C.mob, /mob/dead))
|
||||
log_access("AFK: [key_name(C)]")
|
||||
to_chat(C, "<span class='danger'>You have been inactive for more than 10 minutes and have been disconnected.</span>")
|
||||
qdel(C)
|
||||
|
||||
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*world.tick_usage/100]")
|
||||
|
||||
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
|
||||
return
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ PROCESSING_SUBSYSTEM_DEF(flightpacks)
|
||||
stat_tag = "FM"
|
||||
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING
|
||||
|
||||
var/flightsuit_processing = FLIGHTSUIT_PROCESSING_FULL
|
||||
var/flightsuit_processing = FLIGHTSUIT_PROCESSING_NONE
|
||||
|
||||
/datum/controller/subsystem/processing/flightpacks/Initialize()
|
||||
sync_flightsuit_processing()
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
#define PING_BUFFER_TIME 25
|
||||
|
||||
SUBSYSTEM_DEF(server_maint)
|
||||
name = "Server Tasks"
|
||||
wait = 6000
|
||||
flags = SS_NO_TICK_CHECK
|
||||
wait = 6
|
||||
flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
|
||||
priority = 10
|
||||
var/list/currentrun
|
||||
|
||||
/datum/controller/subsystem/server_maint/Initialize(timeofday)
|
||||
if (config.hub)
|
||||
world.visibility = 1
|
||||
..()
|
||||
|
||||
/datum/controller/subsystem/server_maint/fire()
|
||||
//handle kicking inactive players
|
||||
if(config.kick_inactive)
|
||||
for(var/client/C in GLOB.clients)
|
||||
/datum/controller/subsystem/server_maint/fire(resumed = FALSE)
|
||||
if(!resumed)
|
||||
src.currentrun = GLOB.clients.Copy()
|
||||
|
||||
var/list/currentrun = src.currentrun
|
||||
var/round_started = SSticker.HasRoundStarted()
|
||||
|
||||
for(var/I in currentrun)
|
||||
var/client/C = I
|
||||
//handle kicking inactive players
|
||||
if(round_started && config.kick_inactive)
|
||||
if(C.is_afk(config.afk_period))
|
||||
var/cmob = C.mob
|
||||
if(!(istype(cmob, /mob/dead/observer) || (istype(cmob, /mob/dead) && C.holder)))
|
||||
@@ -19,5 +30,10 @@ SUBSYSTEM_DEF(server_maint)
|
||||
to_chat(C, "<span class='danger'>You have been inactive for more than [config.afk_period / 600] minutes and have been disconnected.</span>")
|
||||
qdel(C)
|
||||
|
||||
if(config.sql_enabled)
|
||||
sql_poll_population()
|
||||
if (!(!C || world.time - C.connection_time < PING_BUFFER_TIME || C.inactivity >= (wait-1)))
|
||||
winset(C, null, "command=.update_ping+[world.time+world.tick_lag*world.tick_usage/100]")
|
||||
|
||||
if (MC_TICK_CHECK) //one day, when ss13 has 1000 people per server, you guys are gonna be glad I added this tick check
|
||||
return
|
||||
|
||||
#undef PING_BUFFER_TIME
|
||||
|
||||
@@ -243,7 +243,7 @@ SUBSYSTEM_DEF(ticker)
|
||||
send2irc("Server", "Round of [hide_mode ? "secret":"[mode.name]"] has started[allmins.len ? ".":" with no active admins online!"]")
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/OnRoundstart(datum/callback/cb)
|
||||
if(current_state < GAME_STATE_PLAYING)
|
||||
if(!HasRoundStarted())
|
||||
LAZYADD(round_start_events, cb)
|
||||
else
|
||||
cb.InvokeAsync()
|
||||
@@ -625,8 +625,8 @@ SUBSYSTEM_DEF(ticker)
|
||||
if(selected_tip)
|
||||
m = selected_tip
|
||||
else
|
||||
var/list/randomtips = world.file2list("config/tips.txt")
|
||||
var/list/memetips = world.file2list("config/sillytips.txt")
|
||||
var/list/randomtips = world.file2list("strings/tips.txt")
|
||||
var/list/memetips = world.file2list("strings/sillytips.txt")
|
||||
if(randomtips.len && prob(95))
|
||||
m = pick(randomtips)
|
||||
else if(memetips.len)
|
||||
@@ -672,15 +672,16 @@ SUBSYSTEM_DEF(ticker)
|
||||
return
|
||||
INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate)
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/HasRoundStarted()
|
||||
return current_state >= GAME_STATE_PLAYING
|
||||
|
||||
/datum/controller/subsystem/ticker/proc/IsRoundInProgress()
|
||||
return current_state == GAME_STATE_PLAYING
|
||||
|
||||
/proc/send_gamemode_vote()
|
||||
SSticker.modevoted = TRUE
|
||||
SSvote.initiate_vote("roundtype","server")
|
||||
|
||||
/world/proc/has_round_started()
|
||||
if (SSticker && SSticker.current_state >= GAME_STATE_PLAYING)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/datum/controller/subsystem/ticker/Recover()
|
||||
current_state = SSticker.current_state
|
||||
force_ending = SSticker.force_ending
|
||||
|
||||
@@ -124,7 +124,7 @@ SUBSYSTEM_DEF(vote)
|
||||
if("gamemode")
|
||||
if(GLOB.master_mode != .)
|
||||
world.save_mode(.)
|
||||
if(SSticker && SSticker.mode)
|
||||
if(SSticker.HasRoundStarted())
|
||||
restart = 1
|
||||
else
|
||||
GLOB.master_mode = .
|
||||
|
||||
Reference in New Issue
Block a user