Bleeding edgy refresh (#303)

* not code stuff

* other things

* global vars, defines, helpers

* onclick hud stuff, orphans, world.dm

* controllers and datums

* game folder

* everything not client/mobs in modules

* client folder

* stage 1 mob stuff

* simple animal things

* silicons

* carbon things

* ayylmaos and monkeys

* hyoomahn

* icons n shit

* sprite fixes

* compile fixes

* some fixes I cherrypicked.

* qdel fixes

* forgot brain refractors
This commit is contained in:
Poojawa
2017-03-21 11:44:10 -05:00
committed by GitHub
parent 099a6c8764
commit f67e9f6d87
1476 changed files with 344416 additions and 40694 deletions
+6 -5
View File
@@ -1,8 +1,10 @@
// Clickable stat() button.
/obj/effect/statclick
name = "Initializing..."
var/target
/obj/effect/statclick/New(text, target)
/obj/effect/statclick/New(loc, text, target) //Don't port this to Initialize it's too critical
..()
name = text
src.target = target
@@ -14,10 +16,10 @@
var/class
/obj/effect/statclick/debug/Click()
if(!usr.client.holder)
if(!usr.client.holder || !target)
return
if(!class)
if(istype(target, /datum/subsystem))
if(istype(target, /datum/controller/subsystem))
class = "subsystem"
else if(istype(target, /datum/controller))
class = "controller"
@@ -40,8 +42,7 @@
return
switch(controller)
if("Master")
new/datum/controller/master()
Master.process()
Recreate_MC()
feedback_add_details("admin_verb","RMC")
if("Failsafe")
new /datum/controller/failsafe()
+42 -37
View File
@@ -5,23 +5,24 @@
#define SECURITY_HAS_MAINT_ACCESS 2
#define EVERYONE_HAS_MAINT_ACCESS 4
//Not accessible from usual debug controller verb
/datum/protected_configuration
var/autoadmin = 0
var/autoadmin_rank = "Game Admin"
/datum/configuration/vv_get_var(var_name)
var/static/list/banned_views = list("autoadmin", "autoadmin_rank")
if(var_name in banned_views)
return debug_variable(var_name, "SECRET", 0, src)
return ..()
/datum/protected_configuration/SDQL_update()
return FALSE
/datum/protected_configuration/vv_get_var(var_name)
return debug_variable(var_name, "SECRET", 0, src)
/datum/protected_configuration/vv_edit_var(var_name, var_value)
return FALSE
/datum/configuration/vv_edit_var(var_name, var_value)
var/static/list/banned_edits = list("cross_address", "cross_allowed", "autoadmin", "autoadmin_rank")
if(var_name in banned_edits)
return FALSE
return ..()
/datum/configuration
var/name = "Configuration" // datum name
var/autoadmin = 0
var/autoadmin_rank = "Game Admin"
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)
@@ -218,10 +219,11 @@
var/announce_admin_logout = 0
var/announce_admin_login = 0
var/list/datum/votablemap/maplist = list()
var/datum/votablemap/defaultmap = null
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
@@ -239,6 +241,8 @@
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
@@ -251,6 +255,9 @@
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_safe_latejoin = FALSE //Require the arrivals shuttle to be operational in order for latejoiners to join
/datum/configuration/New()
gamemode_cache = typecacheof(/datum/game_mode,TRUE)
for(var/T in gamemode_cache)
@@ -418,9 +425,9 @@
if(value != "default_pwd" && length(value) > 6) //It's the default value or less than 6 characters long, warn badmins
global.comms_allowed = 1
if("cross_server_address")
global.cross_address = value
cross_address = value
if(value != "byond:\\address:port")
global.cross_allowed = 1
cross_allowed = 1
if("cross_comms_name")
cross_name = value
if("panic_server_name")
@@ -488,12 +495,14 @@
config.announce_admin_login = 1
if("maprotation")
config.maprotation = 1
if("allow_map_voting")
config.allow_map_voting = text2num(value)
if("maprotationchancedelta")
config.maprotatechancedelta = text2num(value)
if("autoadmin")
protected_config.autoadmin = 1
config.autoadmin = 1
if(value)
protected_config.autoadmin_rank = ckeyEx(value)
config.autoadmin_rank = ckeyEx(value)
if("generate_minimaps")
config.generate_minimaps = 1
if("client_warn_version")
@@ -516,12 +525,6 @@
error_silence_time = text2num(value)
if("error_msg_delay")
error_msg_delay = text2num(value)
if("announce_adminhelps")
config.announce_adminhelps = 1
if("discord_url")
config.discord_url = value
if("discord_password")
config.discord_password = value
else
diary << "Unknown setting in configuration: '[name]'"
@@ -749,6 +752,10 @@
MAX_EX_LIGHT_RANGE = BombCap
MAX_EX_FLASH_RANGE = BombCap
MAX_EX_FLAME_RANGE = BombCap
if("arrivals_shuttle_dock_window")
config.arrivals_shuttle_dock_window = max(PARALLAX_LOOP_TIME, text2num(value))
if("arrivals_shuttle_require_safe_latejoin")
config.arrivals_shuttle_require_safe_latejoin = text2num(value)
else
diary << "Unknown setting in configuration: '[name]'"
@@ -760,7 +767,7 @@
/datum/configuration/proc/loadmaplist(filename)
var/list/Lines = file2list(filename)
var/datum/votablemap/currentmap = null
var/datum/map_config/currentmap = null
for(var/t in Lines)
if(!t)
continue
@@ -789,21 +796,19 @@
switch (command)
if ("map")
currentmap = new (data)
if ("friendlyname")
currentmap.friendlyname = data
currentmap = new ("_maps/[data].json")
if(currentmap.defaulted)
log_world("Failed to load map config for [data]!")
if ("minplayers","minplayer")
currentmap.minusers = text2num(data)
currentmap.config_min_users = text2num(data)
if ("maxplayers","maxplayer")
currentmap.maxusers = text2num(data)
if ("friendlyname")
currentmap.friendlyname = data
currentmap.config_max_users = text2num(data)
if ("weight","voteweight")
currentmap.voteweight = text2num(data)
if ("default","defaultmap")
config.defaultmap = currentmap
if ("endmap")
config.maplist[currentmap.name] = currentmap
config.maplist[currentmap.map_name] = currentmap
currentmap = null
else
diary << "Unknown command in map vote config: '[command]'"
@@ -866,7 +871,7 @@
var/list/datum/game_mode/runnable_modes = new
for(var/T in gamemode_cache)
var/datum/game_mode/M = new T()
//world << "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]"
//to_chat(world, "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]")
if(!(M.config_tag in modes))
qdel(M)
continue
@@ -879,7 +884,7 @@
M.maximum_players = max_pop[M.config_tag]
if(M.can_start())
runnable_modes[M] = probabilities[M.config_tag]
//world << "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]"
//to_chat(world, "DEBUG: runnable_mode\[[runnable_modes.len]\] = [M.config_tag]")
return runnable_modes
/datum/configuration/proc/get_runnable_midround_modes(crew)
@@ -904,6 +909,6 @@
/datum/configuration/proc/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug("Edit", src)
statclick = new/obj/effect/statclick/debug(null, "Edit", src)
stat("[name]:", statclick)
stat("[name]:", statclick)
+16 -1
View File
@@ -1,4 +1,19 @@
/datum/controller
var/name
// The object used for the clickable stat() button.
var/obj/effect/statclick/statclick
var/obj/effect/statclick/statclick
/datum/controller/proc/Initialize()
//cleanup actions
/datum/controller/proc/Shutdown()
//when we enter dmm_suite.load_map
/datum/controller/proc/StartLoadingMap()
//when we exit dmm_suite.load_map
/datum/controller/proc/StopLoadingMap()
/datum/controller/proc/Recover()
/datum/controller/proc/stat_entry()
+15 -12
View File
@@ -20,6 +20,7 @@ var/datum/controller/failsafe/Failsafe
// Track the MC iteration to make sure its still on track.
var/master_iteration = 0
var/running = TRUE
/datum/controller/failsafe/New()
// Highlander-style: there can only be one! Kill off the old and replace it with the new.
@@ -27,19 +28,21 @@ var/datum/controller/failsafe/Failsafe
if(istype(Failsafe))
qdel(Failsafe)
Failsafe = src
LaunchLoop()
Initialize()
/datum/controller/failsafe/proc/LaunchLoop()
/datum/controller/failsafe/Initialize()
set waitfor = 0
Failsafe.Loop()
qdel(Failsafe) //when Loop() returns, we delete ourselves and let the mc recreate us
if(!QDELETED(src))
qdel(src) //when Loop() returns, we delete ourselves and let the mc recreate us
/datum/controller/failsafe/Destroy()
running = FALSE
..()
return QDEL_HINT_HARDDEL_NOW
/datum/controller/failsafe/proc/Loop()
while(1)
while(running)
lasttick = world.time
if(!Master)
// Replace the missing Master! This should never, ever happen.
@@ -53,23 +56,23 @@ var/datum/controller/failsafe/Failsafe
if(4,5)
--defcon
if(3)
admins << "<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks."
to_chat(admins, "<span class='adminnotice'>Notice: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks.")
--defcon
if(2)
admins << "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>"
to_chat(admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has not fired in the last [(5-defcon) * processing_interval] ticks. Automatic restart in [processing_interval] ticks.</span>")
--defcon
if(1)
admins << "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>"
to_chat(admins, "<span class='boldannounce'>Warning: DEFCON [defcon_pretty()]. The Master Controller has still not fired within the last [(5-defcon) * processing_interval] ticks. Killing and restarting...</span>")
--defcon
var/rtn = Recreate_MC()
if(rtn > 0)
defcon = 4
master_iteration = 0
admins << "<span class='adminnotice'>MC restarted successfully</span>"
to_chat(admins, "<span class='adminnotice'>MC restarted successfully</span>")
else if(rtn < 0)
log_game("FailSafe: Could not restart MC, runtime encountered. Entering defcon 0")
admins << "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>"
to_chat(admins, "<span class='boldannounce'>ERROR: DEFCON [defcon_pretty()]. Could not restart MC, runtime encountered. I will silently keep retrying.</span>")
//if the return number was 0, it just means the mc was restarted too recently, and it just needs some time before we try again
//no need to handle that specially when defcon 0 can handle it
if(0) //DEFCON 0! (mc failed to restart)
@@ -77,7 +80,7 @@ var/datum/controller/failsafe/Failsafe
if(rtn > 0)
defcon = 4
master_iteration = 0
admins << "<span class='adminnotice'>MC restarted successfully</span>"
to_chat(admins, "<span class='adminnotice'>MC restarted successfully</span>")
else
defcon = min(defcon + 1,5)
master_iteration = Master.iteration
@@ -92,8 +95,8 @@ var/datum/controller/failsafe/Failsafe
/datum/controller/failsafe/proc/defcon_pretty()
return defcon
/datum/controller/failsafe/proc/stat_entry()
/datum/controller/failsafe/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Failsafe Controller:", statclick.update("Defcon: [defcon_pretty()] (Interval: [Failsafe.processing_interval] | Iteration: [Failsafe.master_iteration])"))
+26 -26
View File
@@ -46,8 +46,8 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
// The type of the last subsystem to be process()'d.
var/last_type_processed
var/datum/subsystem/queue_head //Start of queue linked list
var/datum/subsystem/queue_tail //End of queue linked list (used for appending to the list)
var/datum/controller/subsystem/queue_head //Start of queue linked list
var/datum/controller/subsystem/queue_tail //End of queue linked list (used for appending to the list)
var/queue_priority_count = 0 //Running total so that we don't have to loop thru the queue each run to split up the tick
var/queue_priority_count_bg = 0 //Same, but for background subsystems
var/map_loading = FALSE //Are we loading in a new map?
@@ -60,7 +60,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
Recover()
qdel(Master)
else
init_subtypes(/datum/subsystem, subsystems)
init_subtypes(/datum/controller/subsystem, subsystems)
Master = src
/datum/controller/master/Destroy()
@@ -68,9 +68,9 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
// Tell qdel() to Del() this object.
return QDEL_HINT_HARDDEL_NOW
/datum/controller/master/proc/Shutdown()
/datum/controller/master/Shutdown()
processing = FALSE
for(var/datum/subsystem/ss in subsystems)
for(var/datum/controller/subsystem/ss in subsystems)
ss.Shutdown()
// Returns 1 if we created a new mc, 0 if we couldn't due to a recent restart,
@@ -93,7 +93,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
return 1
/datum/controller/master/proc/Recover()
/datum/controller/master/Recover()
var/msg = "## DEBUG: [time2text(world.timeofday)] MC restarted. Reports:\n"
for (var/varname in Master.vars)
switch (varname)
@@ -111,22 +111,22 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
subsystems = Master.subsystems
StartProcessing(10)
else
world << "<span class='boldannounce'>The Master Controller is having some issues, we will need to re-initialize EVERYTHING</span>"
Setup(20, TRUE)
to_chat(world, "<span class='boldannounce'>The Master Controller is having some issues, we will need to re-initialize EVERYTHING</span>")
Initialize(20, TRUE)
// Please don't stuff random bullshit here,
// Make a subsystem, give it the SS_NO_FIRE flag, and do your work in it's Initialize()
/datum/controller/master/proc/Setup(delay, init_sss)
/datum/controller/master/Initialize(delay, init_sss)
set waitfor = 0
if(delay)
sleep(delay)
if(init_sss)
init_subtypes(/datum/subsystem, subsystems)
init_subtypes(/datum/controller/subsystem, subsystems)
world << "<span class='boldannounce'>Initializing subsystems...</span>"
to_chat(world, "<span class='boldannounce'>Initializing subsystems...</span>")
// Sort subsystems by init_order, so they initialize in the correct order.
sortTim(subsystems, /proc/cmp_subsystem_init)
@@ -134,7 +134,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
var/start_timeofday = REALTIMEOFDAY
// Initialize subsystems.
CURRENT_TICKLIMIT = config.tick_limit_mc_init
for (var/datum/subsystem/SS in subsystems)
for (var/datum/controller/subsystem/SS in subsystems)
if (SS.flags & SS_NO_INIT)
continue
SS.Initialize(REALTIMEOFDAY)
@@ -143,7 +143,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initializations complete within [time] second[time == 1 ? "" : "s"]!"
world << "<span class='boldannounce'>[msg]</span>"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
log_world(msg)
// Sort subsystems by display setting for easy access.
@@ -161,7 +161,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
/datum/controller/master/proc/RoundStart()
round_started = 1
var/timer = world.time
for (var/datum/subsystem/SS in subsystems)
for (var/datum/controller/subsystem/SS in subsystems)
if (SS.flags & SS_FIRE_IN_LOBBY || SS.flags & SS_TICKER)
continue //already firing
// Stagger subsystems.
@@ -199,7 +199,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
var/list/lobbysubsystems = list()
var/timer = world.time
for (var/thing in subsystems)
var/datum/subsystem/SS = thing
var/datum/controller/subsystem/SS = thing
if (SS.flags & SS_NO_FIRE)
continue
SS.queued_time = 0
@@ -261,7 +261,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
sleep_delta += 1
if (make_runtime)
var/datum/subsystem/SS
var/datum/controller/subsystem/SS
SS.can_fire = 0
if (!Failsafe || (Failsafe.processing_interval > 0 && (Failsafe.lasttick+(Failsafe.processing_interval*5)) < world.time))
new/datum/controller/failsafe() // (re)Start the failsafe.
@@ -313,7 +313,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
. = 0 //so the mc knows if we runtimed
//we create our variables outside of the loops to save on overhead
var/datum/subsystem/SS
var/datum/controller/subsystem/SS
var/SS_flags
for (var/thing in subsystemstocheck)
@@ -339,7 +339,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
// Run thru the queue of subsystems to run, running them while balancing out their allocated tick precentage
/datum/controller/master/proc/RunQueue()
. = 0
var/datum/subsystem/queue_node
var/datum/controller/subsystem/queue_node
var/queue_node_flags
var/queue_node_priority
var/queue_node_paused
@@ -465,7 +465,7 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
var/subsystemstocheck = subsystems + ticker_SS + normal_SS + lobby_SS
for (var/thing in subsystemstocheck)
var/datum/subsystem/SS = thing
var/datum/controller/subsystem/SS = thing
if (!SS || !istype(SS))
//list(SS) is so if a list makes it in the subsystem list, we remove the list, not the contents
subsystems -= list(SS)
@@ -496,24 +496,24 @@ var/CURRENT_TICKLIMIT = TICK_LIMIT_RUNNING
/datum/controller/master/proc/stat_entry()
/datum/controller/master/stat_entry()
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
stat("Byond:", "(FPS:[world.fps]) (TickCount:[world.time/world.tick_lag]) (TickDrift:[round(Master.tickdrift,1)]([round((Master.tickdrift/(world.time/world.tick_lag))*100,0.1)]%))")
stat("Master Controller:", statclick.update("(TickRate:[Master.processing]) (Iteration:[Master.iteration])"))
/datum/controller/master/proc/StartLoadingMap()
/datum/controller/master/StartLoadingMap()
//disallow more than one map to load at once, multithreading it will just cause race conditions
while(map_loading)
stoplag()
for(var/S in subsystems)
var/datum/subsystem/SS = S
var/datum/controller/subsystem/SS = S
SS.StartLoadingMap()
map_loading = TRUE
/datum/controller/master/proc/StopLoadingMap(bounds = null)
/datum/controller/master/StopLoadingMap(bounds = null)
map_loading = FALSE
for(var/S in subsystems)
var/datum/subsystem/SS = S
SS.StopLoadingMap()
var/datum/controller/subsystem/SS = S
SS.StopLoadingMap()
+22 -37
View File
@@ -1,11 +1,10 @@
/datum/subsystem
/datum/controller/subsystem
// Metadata; you should define these.
var/name = "fire coderbus" //name of the subsystem
name = "fire coderbus" //name of the subsystem
var/init_order = 0 //order of initialization. Higher numbers are initialized first, lower numbers later. Can be decimal and negative values.
var/wait = 20 //time to wait (in deciseconds) between each call to fire(). Must be a positive integer.
var/display_order = 100 //display affects the order the subsystem is displayed in the MC tab
var/priority = 50 //When mutiple subsystems need to run in the same tick, higher priority subsystems will run first and be given a higher share of the tick before MC_TICK_CHECK triggers a sleep
var/flags = 0 //see MC.dm in __DEFINES Most flags must be set on world start to take full effect. (You can also restart the mc to force them to process again)
@@ -27,22 +26,14 @@
var/queued_time = 0 //time we entered the queue, (for timing and priority reasons)
var/queued_priority //we keep a running total to make the math easier, if priority changes mid-fire that would break our running total, so we store it here
//linked list stuff for the queue
var/datum/subsystem/queue_next
var/datum/subsystem/queue_prev
// The object used for the clickable stat() button.
var/obj/effect/statclick/statclick
var/datum/controller/subsystem/queue_next
var/datum/controller/subsystem/queue_prev
// Used to initialize the subsystem BEFORE the map has loaded
/datum/subsystem/New()
//cleanup actions
/datum/subsystem/proc/Shutdown()
return
/datum/controller/subsystem/New()
//This is used so the mc knows when the subsystem sleeps. do not override.
/datum/subsystem/proc/ignite(resumed = 0)
/datum/controller/subsystem/proc/ignite(resumed = 0)
set waitfor = 0
. = SS_SLEEPING
fire(resumed)
@@ -58,11 +49,11 @@
//previously, this would have been named 'process()' but that name is used everywhere for different things!
//fire() seems more suitable. This is the procedure that gets called every 'wait' deciseconds.
//Sleeping in here prevents future fires until returned.
/datum/subsystem/proc/fire(resumed = 0)
/datum/controller/subsystem/proc/fire(resumed = 0)
flags |= SS_NO_FIRE
throw EXCEPTION("Subsystem [src]([type]) does not fire() but did not set the SS_NO_FIRE flag. Please add the SS_NO_FIRE flag to any subsystem that doesn't fire so it doesn't get added to the processing list and waste cpu.")
/datum/subsystem/Destroy()
/datum/controller/subsystem/Destroy()
dequeue()
can_fire = 0
flags |= SS_NO_FIRE
@@ -72,10 +63,10 @@
//Queue it to run.
// (we loop thru a linked list until we get to the end or find the right point)
// (this lets us sort our run order correctly without having to re-sort the entire already sorted list)
/datum/subsystem/proc/enqueue()
/datum/controller/subsystem/proc/enqueue()
var/SS_priority = priority
var/SS_flags = flags
var/datum/subsystem/queue_node
var/datum/controller/subsystem/queue_node
var/queue_node_priority
var/queue_node_flags
@@ -130,7 +121,7 @@
queue_node.queue_prev = src
/datum/subsystem/proc/dequeue()
/datum/controller/subsystem/proc/dequeue()
if (queue_next)
queue_next.queue_prev = queue_prev
if (queue_prev)
@@ -144,7 +135,7 @@
state = SS_IDLE
/datum/subsystem/proc/pause()
/datum/controller/subsystem/proc/pause()
. = 1
if (state == SS_RUNNING)
state = SS_PAUSED
@@ -153,17 +144,17 @@
//used to initialize the subsystem AFTER the map has loaded
/datum/subsystem/proc/Initialize(start_timeofday)
/datum/controller/subsystem/Initialize(start_timeofday)
var/time = (REALTIMEOFDAY - start_timeofday) / 10
var/msg = "Initialized [name] subsystem within [time] second[time == 1 ? "" : "s"]!"
world << "<span class='boldannounce'>[msg]</span>"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
log_world(msg)
return time
//hook for printing stats to the "MC" statuspanel for admins to see performance and related stats etc.
/datum/subsystem/proc/stat_entry(msg)
/datum/controller/subsystem/stat_entry(msg)
if(!statclick)
statclick = new/obj/effect/statclick/debug("Initializing...", src)
statclick = new/obj/effect/statclick/debug(null, "Initializing...", src)
@@ -178,7 +169,7 @@
stat(title, statclick.update(msg))
/datum/subsystem/proc/state_letter()
/datum/controller/subsystem/proc/state_letter()
switch (state)
if (SS_RUNNING)
. = "R"
@@ -193,15 +184,15 @@
//could be used to postpone a costly subsystem for (default one) var/cycles, cycles
//for instance, during cpu intensive operations like explosions
/datum/subsystem/proc/postpone(cycles = 1)
/datum/controller/subsystem/proc/postpone(cycles = 1)
if(next_fire - world.time < wait)
next_fire += (wait*cycles)
//usually called via datum/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash)
//usually called via datum/controller/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash)
//should attempt to salvage what it can from the old instance of subsystem
/datum/subsystem/proc/Recover()
/datum/controller/subsystem/Recover()
/datum/subsystem/vv_edit_var(var_name, var_value)
/datum/controller/subsystem/vv_edit_var(var_name, var_value)
switch (var_name)
if ("can_fire")
//this is so the subsystem doesn't rapid fire to make up missed ticks causing more lag
@@ -209,10 +200,4 @@
next_fire = world.time + wait
if ("queued_priority") //editing this breaks things.
return 0
. = ..()
//when we enter dmm_suite.load_map
/datum/subsystem/proc/StartLoadingMap()
//when we exit dmm_suite.load_map
/datum/subsystem/proc/StopLoadingMap()
. = ..()
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/acid/SSacid
var/datum/controller/subsystem/acid/SSacid
/datum/subsystem/acid
/datum/controller/subsystem/acid
name = "Acid"
priority = 40
flags = SS_NO_INIT|SS_BACKGROUND
@@ -8,15 +8,15 @@ var/datum/subsystem/acid/SSacid
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/acid/New()
/datum/controller/subsystem/acid/New()
NEW_SS_GLOBAL(SSacid)
/datum/subsystem/acid/stat_entry()
/datum/controller/subsystem/acid/stat_entry()
..("P:[processing.len]")
/datum/subsystem/acid/fire(resumed = 0)
/datum/controller/subsystem/acid/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+25 -27
View File
@@ -5,15 +5,14 @@
#define SSAIR_HIGHPRESSURE 5
#define SSAIR_HOTSPOTS 6
#define SSAIR_SUPERCONDUCTIVITY 7
var/datum/subsystem/air/SSair
var/datum/controller/subsystem/air/SSair
/datum/subsystem/air
/datum/controller/subsystem/air
name = "Air"
init_order = -1
priority = 20
wait = 5
flags = SS_BACKGROUND
display_order = 1
var/cost_turfs = 0
var/cost_groups = 0
@@ -42,10 +41,10 @@ var/datum/subsystem/air/SSair
var/map_loading = TRUE
var/list/queued_for_activation
/datum/subsystem/air/New()
/datum/controller/subsystem/air/New()
NEW_SS_GLOBAL(SSair)
/datum/subsystem/air/stat_entry(msg)
/datum/controller/subsystem/air/stat_entry(msg)
msg += "C:{"
msg += "AT:[round(cost_turfs,1)]|"
msg += "EG:[round(cost_groups,1)]|"
@@ -65,7 +64,7 @@ var/datum/subsystem/air/SSair
..(msg)
/datum/subsystem/air/Initialize(timeofday)
/datum/controller/subsystem/air/Initialize(timeofday)
map_loading = FALSE
setup_allturfs()
setup_atmos_machinery()
@@ -73,7 +72,7 @@ var/datum/subsystem/air/SSair
..()
/datum/subsystem/air/fire(resumed = 0)
/datum/controller/subsystem/air/fire(resumed = 0)
var/timer = world.tick_usage
if(currentpart == SSAIR_PIPENETS || !resumed)
@@ -140,7 +139,7 @@ var/datum/subsystem/air/SSair
/datum/subsystem/air/proc/process_pipenets(resumed = 0)
/datum/controller/subsystem/air/proc/process_pipenets(resumed = 0)
if (!resumed)
src.currentrun = networks.Copy()
//cache for sanic speed (lists are references anyways)
@@ -156,7 +155,7 @@ var/datum/subsystem/air/SSair
return
/datum/subsystem/air/proc/process_atmos_machinery(resumed = 0)
/datum/controller/subsystem/air/proc/process_atmos_machinery(resumed = 0)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = atmos_machinery.Copy()
@@ -171,7 +170,7 @@ var/datum/subsystem/air/SSair
return
/datum/subsystem/air/proc/process_super_conductivity(resumed = 0)
/datum/controller/subsystem/air/proc/process_super_conductivity(resumed = 0)
if (!resumed)
src.currentrun = active_super_conductivity.Copy()
//cache for sanic speed (lists are references anyways)
@@ -183,7 +182,7 @@ var/datum/subsystem/air/SSair
if(MC_TICK_CHECK)
return
/datum/subsystem/air/proc/process_hotspots(resumed = 0)
/datum/controller/subsystem/air/proc/process_hotspots(resumed = 0)
if (!resumed)
src.currentrun = hotspots.Copy()
//cache for sanic speed (lists are references anyways)
@@ -199,17 +198,16 @@ var/datum/subsystem/air/SSair
return
/datum/subsystem/air/proc/process_high_pressure_delta(resumed = 0)
/datum/controller/subsystem/air/proc/process_high_pressure_delta(resumed = 0)
while (high_pressure_delta.len)
var/turf/open/T = high_pressure_delta[high_pressure_delta.len]
high_pressure_delta.len--
if (isturf(T))
T.high_pressure_movements()
T.pressure_difference = 0
T.high_pressure_movements()
T.pressure_difference = 0
if(MC_TICK_CHECK)
return
/datum/subsystem/air/proc/process_active_turfs(resumed = 0)
/datum/controller/subsystem/air/proc/process_active_turfs(resumed = 0)
//cache for sanic speed
var/fire_count = times_fired
if (!resumed)
@@ -219,12 +217,12 @@ var/datum/subsystem/air/SSair
while(currentrun.len)
var/turf/open/T = currentrun[currentrun.len]
currentrun.len--
if (T && isturf(T))
if (T)
T.process_cell(fire_count)
if (MC_TICK_CHECK)
return
/datum/subsystem/air/proc/process_excited_groups(resumed = 0)
/datum/controller/subsystem/air/proc/process_excited_groups(resumed = 0)
if (!resumed)
src.currentrun = excited_groups.Copy()
//cache for sanic speed (lists are references anyways)
@@ -242,7 +240,7 @@ var/datum/subsystem/air/SSair
return
/datum/subsystem/air/proc/remove_from_active(turf/open/T)
/datum/controller/subsystem/air/proc/remove_from_active(turf/open/T)
active_turfs -= T
if(currentpart == SSAIR_ACTIVETURFS)
currentrun -= T
@@ -251,7 +249,7 @@ var/datum/subsystem/air/SSair
if(T.excited_group)
T.excited_group.garbage_collect()
/datum/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
/datum/controller/subsystem/air/proc/add_to_active(turf/open/T, blockchanges = 1)
if(istype(T) && T.air)
T.excited = 1
active_turfs |= T
@@ -269,17 +267,17 @@ var/datum/subsystem/air/SSair
else
T.requires_activation = TRUE
/datum/subsystem/air/StartLoadingMap()
/datum/controller/subsystem/air/StartLoadingMap()
LAZYINITLIST(queued_for_activation)
map_loading = TRUE
/datum/subsystem/air/StopLoadingMap()
/datum/controller/subsystem/air/StopLoadingMap()
map_loading = FALSE
for(var/T in queued_for_activation)
add_to_active(T)
queued_for_activation.Cut()
/datum/subsystem/air/proc/setup_allturfs()
/datum/controller/subsystem/air/proc/setup_allturfs()
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
var/list/active_turfs = src.active_turfs
var/times_fired = ++src.times_fired
@@ -320,7 +318,7 @@ var/datum/subsystem/air/SSair
CHECK_TICK
var/msg = "HEY! LISTEN! [(world.timeofday - timer)/10] Seconds were wasted processing [starting_ats] turf(s) (connected to [ending_ats] other turfs) with atmos differences at round start."
world << "<span class='boldannounce'>[msg]</span>"
to_chat(world, "<span class='boldannounce'>[msg]</span>")
warning(msg)
/turf/open/proc/resolve_active_graph()
@@ -349,7 +347,7 @@ var/datum/subsystem/air/SSair
/turf/open/space/resolve_active_graph()
return list()
/datum/subsystem/air/proc/setup_atmos_machinery()
/datum/controller/subsystem/air/proc/setup_atmos_machinery()
for (var/obj/machinery/atmospherics/AM in atmos_machinery)
AM.atmosinit()
CHECK_TICK
@@ -357,12 +355,12 @@ var/datum/subsystem/air/SSair
//this can't be done with setup_atmos_machinery() because
// all atmos machinery has to initalize before the first
// pipenet can be built.
/datum/subsystem/air/proc/setup_pipenets()
/datum/controller/subsystem/air/proc/setup_pipenets()
for (var/obj/machinery/atmospherics/AM in atmos_machinery)
AM.build_network()
CHECK_TICK
/datum/subsystem/air/proc/setup_template_machinery(list/atmos_machines)
/datum/controller/subsystem/air/proc/setup_template_machinery(list/atmos_machines)
for(var/A in atmos_machines)
var/obj/machinery/atmospherics/AM = A
AM.atmosinit()
+4 -4
View File
@@ -1,15 +1,15 @@
var/datum/subsystem/assets/SSasset
var/datum/controller/subsystem/assets/SSasset
/datum/subsystem/assets
/datum/controller/subsystem/assets
name = "Assets"
init_order = -3
flags = SS_NO_FIRE
var/list/cache = list()
/datum/subsystem/assets/New()
/datum/controller/subsystem/assets/New()
NEW_SS_GLOBAL(SSasset)
/datum/subsystem/assets/Initialize(timeofday)
/datum/controller/subsystem/assets/Initialize(timeofday)
for(var/type in typesof(/datum/asset) - list(/datum/asset, /datum/asset/simple))
var/datum/asset/A = new type()
A.register()
+21 -9
View File
@@ -1,10 +1,10 @@
var/datum/subsystem/atoms/SSatoms
var/datum/controller/subsystem/atoms/SSatoms
#define INITIALIZATION_INSSATOMS 0 //New should not call Initialize
#define INITIALIZATION_INNEW_MAPLOAD 1 //New should call Initialize(TRUE)
#define INITIALIZATION_INNEW_REGULAR 2 //New should call Initialize(FALSE)
/datum/subsystem/atoms
/datum/controller/subsystem/atoms
name = "Atoms"
init_order = 11
flags = SS_NO_FIRE
@@ -12,17 +12,17 @@ var/datum/subsystem/atoms/SSatoms
var/initialized = INITIALIZATION_INSSATOMS
var/old_initialized
/datum/subsystem/atoms/New()
/datum/controller/subsystem/atoms/New()
NEW_SS_GLOBAL(SSatoms)
/datum/subsystem/atoms/Initialize(timeofday)
/datum/controller/subsystem/atoms/Initialize(timeofday)
fire_overlay.appearance_flags = RESET_COLOR
setupGenetics() //to set the mutations' place in structural enzymes, so monkey.initialize() knows where to put the monkey mutation.
initialized = INITIALIZATION_INNEW_MAPLOAD
InitializeAtoms()
return ..()
/datum/subsystem/atoms/proc/InitializeAtoms(list/atoms = null)
/datum/controller/subsystem/atoms/proc/InitializeAtoms(list/atoms = null)
if(initialized == INITIALIZATION_INSSATOMS)
return
@@ -30,10 +30,17 @@ var/datum/subsystem/atoms/SSatoms
initialized = INITIALIZATION_INNEW_MAPLOAD
var/static/list/NewQdelList = list()
if(atoms)
for(var/I in atoms)
var/atom/A = I
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
if(QDELETED(A))
if(!(NewQdelList[A.type]))
stack_trace("Found new qdeletion in type [A.type]!")
NewQdelList[A.type] = TRUE
continue
var/start_tick = world.time
if(A.Initialize(TRUE))
LAZYADD(late_loaders, A)
@@ -47,6 +54,11 @@ var/datum/subsystem/atoms/SSatoms
#endif
for(var/atom/A in world)
if(!A.initialized) //this check is to make sure we don't call it twice on an object that was created in a previous Initialize call
if(QDELETED(A))
if(!(NewQdelList[A.type]))
stack_trace("Found new qdeletion in type [A.type]!")
NewQdelList[A.type] = TRUE
continue
var/start_tick = world.time
if(A.Initialize(TRUE))
LAZYADD(late_loaders, A)
@@ -71,20 +83,20 @@ var/datum/subsystem/atoms/SSatoms
CHECK_TICK
testing("Late-initialized [late_loaders.len] atoms")
/datum/subsystem/atoms/proc/map_loader_begin()
/datum/controller/subsystem/atoms/proc/map_loader_begin()
old_initialized = initialized
initialized = INITIALIZATION_INSSATOMS
/datum/subsystem/atoms/proc/map_loader_stop()
/datum/controller/subsystem/atoms/proc/map_loader_stop()
initialized = old_initialized
/datum/subsystem/atoms/Recover()
/datum/controller/subsystem/atoms/Recover()
initialized = SSatoms.initialized
if(initialized == INITIALIZATION_INNEW_MAPLOAD)
InitializeAtoms()
old_initialized = SSatoms.old_initialized
/datum/subsystem/atoms/proc/setupGenetics()
/datum/controller/subsystem/atoms/proc/setupGenetics()
var/list/avnums = new /list(DNA_STRUC_ENZYMES_BLOCKS)
for(var/i=1, i<=DNA_STRUC_ENZYMES_BLOCKS, i++)
avnums[i] = i
+8 -8
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/augury/SSaugury
var/datum/controller/subsystem/augury/SSaugury
/datum/subsystem/augury
/datum/controller/subsystem/augury
name = "Augury"
flags = SS_NO_INIT
@@ -9,16 +9,16 @@ var/datum/subsystem/augury/SSaugury
var/list/observers_given_action = list()
/datum/subsystem/augury/New()
/datum/controller/subsystem/augury/New()
NEW_SS_GLOBAL(SSaugury)
/datum/subsystem/augury/stat_entry(msg)
/datum/controller/subsystem/augury/stat_entry(msg)
..("W:[watchers.len]|D:[doombringers.len]")
/datum/subsystem/augury/proc/register_doom(atom/A, severity)
/datum/controller/subsystem/augury/proc/register_doom(atom/A, severity)
doombringers[A] = severity
/datum/subsystem/augury/fire()
/datum/controller/subsystem/augury/fire()
var/biggest_doom = null
var/biggest_threat = null
@@ -67,13 +67,13 @@ var/datum/subsystem/augury/SSaugury
/datum/action/innate/augury/Activate()
SSaugury.watchers += owner
owner << "<span class='notice'>You are now auto-following debris.</span>"
to_chat(owner, "<span class='notice'>You are now auto-following debris.</span>")
active = TRUE
UpdateButtonIcon()
/datum/action/innate/augury/Deactivate()
SSaugury.watchers -= owner
owner << "<span class='notice'>You are no longer auto-following debris.</span>"
to_chat(owner, "<span class='notice'>You are no longer auto-following debris.</span>")
active = FALSE
UpdateButtonIcon()
+5 -5
View File
@@ -1,19 +1,19 @@
#define COMMUNICATION_COOLDOWN 600
#define COMMUNICATION_COOLDOWN_AI 600
var/datum/subsystem/communications/SScommunications
var/datum/controller/subsystem/communications/SScommunications
/datum/subsystem/communications
/datum/controller/subsystem/communications
name = "Communications"
flags = SS_NO_INIT | SS_NO_FIRE
var/silicon_message_cooldown
var/nonsilicon_message_cooldown
/datum/subsystem/communications/New()
/datum/controller/subsystem/communications/New()
NEW_SS_GLOBAL(SScommunications)
/datum/subsystem/communications/proc/can_announce(mob/living/user, is_silicon)
/datum/controller/subsystem/communications/proc/can_announce(mob/living/user, is_silicon)
if(is_silicon && silicon_message_cooldown > world.time)
. = FALSE
else if(!is_silicon && nonsilicon_message_cooldown > world.time)
@@ -21,7 +21,7 @@ var/datum/subsystem/communications/SScommunications
else
. = TRUE
/datum/subsystem/communications/proc/make_announcement(mob/living/user, is_silicon, input)
/datum/controller/subsystem/communications/proc/make_announcement(mob/living/user, is_silicon, input)
if(!can_announce(user, is_silicon))
return FALSE
if(is_silicon)
+5 -5
View File
@@ -1,19 +1,19 @@
var/datum/subsystem/diseases/SSdisease
var/datum/controller/subsystem/diseases/SSdisease
/datum/subsystem/diseases
/datum/controller/subsystem/diseases
name = "Diseases"
flags = SS_KEEP_TIMING|SS_NO_INIT
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/diseases/New()
/datum/controller/subsystem/diseases/New()
NEW_SS_GLOBAL(SSdisease)
/datum/subsystem/diseases/stat_entry(msg)
/datum/controller/subsystem/diseases/stat_entry(msg)
..("P:[processing.len]")
/datum/subsystem/diseases/fire(resumed = 0)
/datum/controller/subsystem/diseases/fire(resumed = 0)
if(!resumed)
src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
+23 -32
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/events/SSevent
var/datum/controller/subsystem/events/SSevent
/datum/subsystem/events
/datum/controller/subsystem/events
name = "Events"
init_order = 6
@@ -16,11 +16,11 @@ var/datum/subsystem/events/SSevent
var/wizardmode = 0
/datum/subsystem/events/New()
/datum/controller/subsystem/events/New()
NEW_SS_GLOBAL(SSevent)
/datum/subsystem/events/Initialize(time, zlevel)
/datum/controller/subsystem/events/Initialize(time, zlevel)
for(var/type in typesof(/datum/round_event_control))
var/datum/round_event_control/E = new type()
if(!E.typepath)
@@ -31,7 +31,7 @@ var/datum/subsystem/events/SSevent
..()
/datum/subsystem/events/fire(resumed = 0)
/datum/controller/subsystem/events/fire(resumed = 0)
if(!resumed)
checkEvent() //only check these if we aren't resuming a paused fire
src.currentrun = running.Copy()
@@ -50,23 +50,18 @@ var/datum/subsystem/events/SSevent
return
//checks if we should select a random event yet, and reschedules if necessary
/datum/subsystem/events/proc/checkEvent()
/datum/controller/subsystem/events/proc/checkEvent()
if(scheduled <= world.time)
spawnEvent()
reschedule()
//decides which world.time we should select another random event at.
/datum/subsystem/events/proc/reschedule()
/datum/controller/subsystem/events/proc/reschedule()
scheduled = world.time + rand(frequency_lower, max(frequency_lower,frequency_upper))
if(world.time > 108000) //2:45
if(SSshuttle.emergency.mode < SHUTTLE_CALL)
SSshuttle.emergency.request(null, 1.5)
log_game("Round time limit reached. Shuttle has been auto-called.")
message_admins("Round time limit reached. Shuttle called.")
//selects a random event based on whether it can occur and it's 'weight'(probability)
/datum/subsystem/events/proc/spawnEvent()
/datum/controller/subsystem/events/proc/spawnEvent()
set waitfor = FALSE //for the admin prompt
if(!config.allow_random_events)
// var/datum/round_event_control/E = locate(/datum/round_event_control/dust) in control
// if(E) E.runEvent()
@@ -81,13 +76,8 @@ var/datum/subsystem/events/SSevent
if(!E.canSpawnEvent(players_amt, gamemode))
continue
if(E.weight < 0) //for round-start events etc.
if(E.runEvent() == PROCESS_KILL)
E.max_occurrences = 0
continue
if (E.alertadmins)
message_admins("Random Event triggering: [E.name] ([E.typepath])")
log_game("Random Event triggering: [E.name] ([E.typepath])")
return
if(TriggerEvent(E))
return
sum_of_weights += E.weight
sum_of_weights = rand(0,sum_of_weights) //reusing this variable. It now represents the 'weight' we want to select
@@ -98,14 +88,15 @@ var/datum/subsystem/events/SSevent
sum_of_weights -= E.weight
if(sum_of_weights <= 0) //we've hit our goal
if(E.runEvent() == PROCESS_KILL)//we couldn't run this event for some reason, set its max_occurrences to 0
E.max_occurrences = 0
continue
if (E.alertadmins)
message_admins("Random Event triggering: [E.name] ([E.typepath])")
deadchat_broadcast("<span class='deadsay'><b>[E.name]</b> has just been randomly triggered!</span>") //STOP ASSUMING IT'S BADMINS!
log_game("Random Event triggering: [E.name] ([E.typepath])")
return
if(TriggerEvent(E))
return
/datum/controller/subsystem/events/proc/TriggerEvent(datum/round_event_control/E)
. = E.preRunEvent()
if(. == EVENT_CANT_RUN)//we couldn't run this event for some reason, set its max_occurrences to 0
E.max_occurrences = 0
else if(. != EVENT_CANCELLED)
E.runEvent(TRUE)
/datum/round_event/proc/findEventArea() //Here's a nice proc to use to find an area for your event to land in!
var/list/safe_areas = list(
@@ -180,7 +171,7 @@ var/datum/subsystem/events/SSevent
*/
//sets up the holidays and holidays list
/datum/subsystem/events/proc/getHoliday()
/datum/controller/subsystem/events/proc/getHoliday()
if(!config.allow_holidays)
return // Holiday stuff was not enabled in the config!
@@ -200,12 +191,12 @@ var/datum/subsystem/events/SSevent
holidays = shuffle(holidays)
world.update_status()
/datum/subsystem/events/proc/toggleWizardmode()
/datum/controller/subsystem/events/proc/toggleWizardmode()
wizardmode = !wizardmode
message_admins("Summon Events has been [wizardmode ? "enabled, events will occur every [SSevent.frequency_lower / 600] to [SSevent.frequency_upper / 600] minutes" : "disabled"]!")
log_game("Summon Events was [wizardmode ? "enabled" : "disabled"]!")
/datum/subsystem/events/proc/resetFrequency()
/datum/controller/subsystem/events/proc/resetFrequency()
frequency_lower = initial(frequency_lower)
frequency_upper = initial(frequency_upper)
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/fire_burning/SSfire_burning
var/datum/controller/subsystem/fire_burning/SSfire_burning
/datum/subsystem/fire_burning
/datum/controller/subsystem/fire_burning
name = "Fire Burning"
priority = 40
flags = SS_NO_INIT|SS_BACKGROUND
@@ -8,15 +8,15 @@ var/datum/subsystem/fire_burning/SSfire_burning
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/fire_burning/New()
/datum/controller/subsystem/fire_burning/New()
NEW_SS_GLOBAL(SSfire_burning)
/datum/subsystem/fire_burning/stat_entry()
/datum/controller/subsystem/fire_burning/stat_entry()
..("P:[processing.len]")
/datum/subsystem/fire_burning/fire(resumed = 0)
/datum/controller/subsystem/fire_burning/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+11 -23
View File
@@ -1,10 +1,9 @@
var/datum/subsystem/garbage_collector/SSgarbage
var/datum/controller/subsystem/garbage_collector/SSgarbage
/datum/subsystem/garbage_collector
/datum/controller/subsystem/garbage_collector
name = "Garbage"
priority = 15
wait = 5
display_order = 2
flags = SS_FIRE_IN_LOBBY|SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT
var/collection_timeout = 3000// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object
@@ -35,10 +34,10 @@ var/datum/subsystem/garbage_collector/SSgarbage
var/list/qdel_list = list() // list of all types that have been qdel()eted
#endif
/datum/subsystem/garbage_collector/New()
/datum/controller/subsystem/garbage_collector/New()
NEW_SS_GLOBAL(SSgarbage)
/datum/subsystem/garbage_collector/stat_entry(msg)
/datum/controller/subsystem/garbage_collector/stat_entry(msg)
msg += "Q:[queue.len]|D:[delslasttick]|G:[gcedlasttick]|"
msg += "GR:"
if (!(delslasttick+gcedlasttick))
@@ -53,14 +52,14 @@ var/datum/subsystem/garbage_collector/SSgarbage
msg += "TGR:[round((totalgcs/(totaldels+totalgcs))*100, 0.01)]%"
..(msg)
/datum/subsystem/garbage_collector/fire()
/datum/controller/subsystem/garbage_collector/fire()
HandleToBeQueued()
if(state == SS_RUNNING)
HandleQueue()
//If you see this proc high on the profile, what you are really seeing is the garbage collection/soft delete overhead in byond.
//Don't attempt to optimize, not worth the effort.
/datum/subsystem/garbage_collector/proc/HandleToBeQueued()
/datum/controller/subsystem/garbage_collector/proc/HandleToBeQueued()
var/list/tobequeued = src.tobequeued
var/starttime = world.time
var/starttimeofday = world.timeofday
@@ -71,7 +70,7 @@ var/datum/subsystem/garbage_collector/SSgarbage
Queue(ref)
tobequeued.Cut(1, 2)
/datum/subsystem/garbage_collector/proc/HandleQueue()
/datum/controller/subsystem/garbage_collector/proc/HandleQueue()
delslasttick = 0
gcedlasttick = 0
var/time_to_kill = world.time - collection_timeout // Anything qdel() but not GC'd BEFORE this time needs to be manually del()
@@ -125,12 +124,12 @@ var/datum/subsystem/garbage_collector/SSgarbage
++gcedlasttick
++totalgcs
/datum/subsystem/garbage_collector/proc/QueueForQueuing(datum/A)
/datum/controller/subsystem/garbage_collector/proc/QueueForQueuing(datum/A)
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
tobequeued += A
A.gc_destroyed = GC_QUEUED_FOR_QUEUING
/datum/subsystem/garbage_collector/proc/Queue(datum/A)
/datum/controller/subsystem/garbage_collector/proc/Queue(datum/A)
if (!istype(A) || (!isnull(A.gc_destroyed) && A.gc_destroyed >= 0))
return
if (A.gc_destroyed == GC_QUEUED_FOR_HARD_DEL)
@@ -146,12 +145,12 @@ var/datum/subsystem/garbage_collector/SSgarbage
queue[refid] = gctime
/datum/subsystem/garbage_collector/proc/HardQueue(datum/A)
/datum/controller/subsystem/garbage_collector/proc/HardQueue(datum/A)
if (istype(A) && A.gc_destroyed == GC_CURRENTLY_BEING_QDELETED)
tobequeued += A
A.gc_destroyed = GC_QUEUED_FOR_HARD_DEL
/datum/subsystem/garbage_collector/Recover()
/datum/controller/subsystem/garbage_collector/Recover()
if (istype(SSgarbage.queue))
queue |= SSgarbage.queue
if (istype(SSgarbage.tobequeued))
@@ -351,9 +350,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
//if find_references isn't working for some datum
//update this list using tools/DMTreeToGlobalsList
/datum/proc/find_references_in_globals()
SearchVar(nextmap)
SearchVar(mapchanging)
SearchVar(rebootingpendingmapchange)
SearchVar(clockwork_construction_value)
SearchVar(clockwork_caches)
SearchVar(clockwork_daemons)
@@ -398,7 +394,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(WALLITEMS_INVERSE)
SearchVar(sortInstance)
SearchVar(config)
SearchVar(protected_config)
SearchVar(host)
SearchVar(join_motd)
SearchVar(station_name)
@@ -416,8 +411,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(Debug2)
SearchVar(comms_key)
SearchVar(comms_allowed)
SearchVar(cross_address)
SearchVar(cross_allowed)
SearchVar(medal_hub)
SearchVar(medal_pass)
SearchVar(medals_enabled)
@@ -477,12 +470,10 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(timezoneOffset)
SearchVar(fileaccess_timer)
SearchVar(TAB)
SearchVar(map_ready)
SearchVar(data_core)
SearchVar(CELLRATE)
SearchVar(CHARGELEVEL)
SearchVar(powernets)
SearchVar(map_name)
SearchVar(hair_styles_list)
SearchVar(hair_styles_male_list)
SearchVar(hair_styles_female_list)
@@ -758,8 +749,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(fire_overlay)
SearchVar(acid_overlay)
SearchVar(BUMP_TELEPORTERS)
SearchVar(contrabandposters)
SearchVar(legitposters)
SearchVar(blacklisted_glowshroom_turfs)
SearchVar(PDAs)
SearchVar(rod_recipes)
@@ -943,7 +932,6 @@ var/datum/subsystem/garbage_collector/SSgarbage
SearchVar(GALOSHES_DONT_HELP)
SearchVar(SLIDE_ICE)
SearchVar(limb_icon_cache)
SearchVar(ALIEN_AFK_BRACKET)
SearchVar(MIN_IMPREGNATION_TIME)
SearchVar(MAX_IMPREGNATION_TIME)
SearchVar(MIN_ACTIVE_TIME)
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/icon_smooth/SSicon_smooth
var/datum/controller/subsystem/icon_smooth/SSicon_smooth
/datum/subsystem/icon_smooth
/datum/controller/subsystem/icon_smooth
name = "Icon Smoothing"
init_order = -5
wait = 1
@@ -9,10 +9,10 @@ var/datum/subsystem/icon_smooth/SSicon_smooth
var/list/smooth_queue = list()
/datum/subsystem/icon_smooth/New()
/datum/controller/subsystem/icon_smooth/New()
NEW_SS_GLOBAL(SSicon_smooth)
/datum/subsystem/icon_smooth/fire()
/datum/controller/subsystem/icon_smooth/fire()
while(smooth_queue.len)
var/atom/A = smooth_queue[smooth_queue.len]
smooth_queue.len--
@@ -22,7 +22,7 @@ var/datum/subsystem/icon_smooth/SSicon_smooth
if (!smooth_queue.len)
can_fire = 0
/datum/subsystem/icon_smooth/Initialize()
/datum/controller/subsystem/icon_smooth/Initialize()
smooth_zlevel(1,TRUE)
smooth_zlevel(2,TRUE)
var/queue = smooth_queue
+32
View File
@@ -0,0 +1,32 @@
var/datum/controller/subsystem/inbounds/SSinbounds
/datum/controller/subsystem/inbounds
name = "Inbounds"
priority = 40
flags = SS_NO_INIT
var/list/processing = list()
var/list/currentrun = list()
/datum/controller/subsystem/inbounds/New()
NEW_SS_GLOBAL(SSinbounds)
/datum/controller/subsystem/inbounds/stat_entry()
..("P:[processing.len]")
/datum/controller/subsystem/inbounds/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
var/list/currentrun = src.currentrun
while(currentrun.len)
var/atom/movable/thing = currentrun[currentrun.len]
currentrun.len--
if(thing)
thing.check_in_bounds(wait)
else
SSinbounds.processing -= thing
if(MC_TICK_CHECK)
return
/datum/controller/subsystem/inbounds/Recover()
processing = SSinbounds.processing
+4 -4
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/ipintel/SSipintel
var/datum/controller/subsystem/ipintel/SSipintel
/datum/subsystem/ipintel
/datum/controller/subsystem/ipintel
name = "XKeyScore"
init_order = -10
flags = SS_NO_FIRE
@@ -10,10 +10,10 @@ var/datum/subsystem/ipintel/SSipintel
var/list/cache = list()
/datum/subsystem/ipintel/New()
/datum/controller/subsystem/ipintel/New()
NEW_SS_GLOBAL(SSipintel)
/datum/subsystem/ipintel/Initialize(timeofday, zlevel)
/datum/controller/subsystem/ipintel/Initialize(timeofday, zlevel)
enabled = 1
. = ..()
+74 -55
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/job/SSjob
var/datum/controller/subsystem/job/SSjob
/datum/subsystem/job
/datum/controller/subsystem/job
name = "Jobs"
init_order = 14
flags = SS_NO_FIRE
@@ -12,11 +12,13 @@ var/datum/subsystem/job/SSjob
var/list/job_debug = list() //Debug info
var/initial_players_to_assign = 0 //used for checking against population caps
/datum/subsystem/job/New()
var/list/prioritized_jobs = list()
/datum/controller/subsystem/job/New()
NEW_SS_GLOBAL(SSjob)
/datum/subsystem/job/Initialize(timeofday)
/datum/controller/subsystem/job/Initialize(timeofday)
if(!occupations.len)
SetupOccupations()
if(config.load_jobs_from_txt)
@@ -24,11 +26,11 @@ var/datum/subsystem/job/SSjob
..()
/datum/subsystem/job/proc/SetupOccupations(faction = "Station")
/datum/controller/subsystem/job/proc/SetupOccupations(faction = "Station")
occupations = list()
var/list/all_jobs = subtypesof(/datum/job)
if(!all_jobs.len)
world << "<span class='boldannounce'>Error setting up jobs, no job datums found</span>"
to_chat(world, "<span class='boldannounce'>Error setting up jobs, no job datums found</span>")
return 0
for(var/J in all_jobs)
@@ -39,6 +41,9 @@ var/datum/subsystem/job/SSjob
continue
if(!job.config_check())
continue
if(!job.map_check()) //Even though we initialize before mapping, this is fine because the config is loaded at new
testing("Removed [job.type] due to map config");
continue
occupations += job
name_occupations[job.title] = job
type_occupations[J] = job
@@ -46,25 +51,24 @@ var/datum/subsystem/job/SSjob
return 1
/datum/subsystem/job/proc/Debug(text)
/datum/controller/subsystem/job/proc/Debug(text)
if(!Debug2)
return 0
job_debug.Add(text)
return 1
/datum/subsystem/job/proc/GetJob(rank)
/datum/controller/subsystem/job/proc/GetJob(rank)
if(!occupations.len)
SetupOccupations()
return name_occupations[rank]
/datum/subsystem/job/proc/GetJobType(jobtype)
/datum/controller/subsystem/job/proc/GetJobType(jobtype)
if(!occupations.len)
SetupOccupations()
return type_occupations[jobtype]
/datum/subsystem/job/proc/AssignRole(mob/new_player/player, rank, latejoin=0)
/datum/controller/subsystem/job/proc/AssignRole(mob/dead/new_player/player, rank, latejoin=0)
Debug("Running AR, Player: [player], Rank: [rank], LJ: [latejoin]")
if(player && player.mind && rank)
var/datum/job/job = GetJob(rank)
@@ -86,10 +90,10 @@ var/datum/subsystem/job/SSjob
return 0
/datum/subsystem/job/proc/FindOccupationCandidates(datum/job/job, level, flag)
/datum/controller/subsystem/job/proc/FindOccupationCandidates(datum/job/job, level, flag)
Debug("Running FOC, Job: [job], Level: [level], Flag: [flag]")
var/list/candidates = list()
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(jobban_isbanned(player, job.title))
Debug("FOC isbanned failed, Player: [player]")
continue
@@ -110,7 +114,7 @@ var/datum/subsystem/job/SSjob
candidates += player
return candidates
/datum/subsystem/job/proc/GiveRandomJob(mob/new_player/player)
/datum/controller/subsystem/job/proc/GiveRandomJob(mob/dead/new_player/player)
Debug("GRJ Giving random job, Player: [player]")
for(var/datum/job/job in shuffle(occupations))
if(!job)
@@ -145,8 +149,8 @@ var/datum/subsystem/job/SSjob
unassigned -= player
break
/datum/subsystem/job/proc/ResetOccupations()
for(var/mob/new_player/player in player_list)
/datum/controller/subsystem/job/proc/ResetOccupations()
for(var/mob/dead/new_player/player in player_list)
if((player) && (player.mind))
player.mind.assigned_role = null
player.mind.special_role = null
@@ -158,7 +162,7 @@ var/datum/subsystem/job/SSjob
//This proc is called before the level loop of DivideOccupations() and will try to select a head, ignoring ALL non-head preferences for every level until
//it locates a head or runs out of levels to check
//This is basically to ensure that there's atleast a few heads in the round
/datum/subsystem/job/proc/FillHeadPosition()
/datum/controller/subsystem/job/proc/FillHeadPosition()
for(var/level = 1 to 3)
for(var/command_position in command_positions)
var/datum/job/job = GetJob(command_position)
@@ -169,7 +173,7 @@ var/datum/subsystem/job/SSjob
var/list/candidates = FindOccupationCandidates(job, level)
if(!candidates.len)
continue
var/mob/new_player/candidate = pick(candidates)
var/mob/dead/new_player/candidate = pick(candidates)
if(AssignRole(candidate, command_position))
return 1
return 0
@@ -177,7 +181,7 @@ var/datum/subsystem/job/SSjob
//This proc is called at the start of the level loop of DivideOccupations() and will cause head jobs to be checked before any other jobs of the same level
//This is also to ensure we get as many heads as possible
/datum/subsystem/job/proc/CheckHeadPositions(level)
/datum/controller/subsystem/job/proc/CheckHeadPositions(level)
for(var/command_position in command_positions)
var/datum/job/job = GetJob(command_position)
if(!job)
@@ -187,12 +191,12 @@ var/datum/subsystem/job/SSjob
var/list/candidates = FindOccupationCandidates(job, level)
if(!candidates.len)
continue
var/mob/new_player/candidate = pick(candidates)
var/mob/dead/new_player/candidate = pick(candidates)
AssignRole(candidate, command_position)
return
/datum/subsystem/job/proc/FillAIPosition()
/datum/controller/subsystem/job/proc/FillAIPosition()
var/ai_selected = 0
var/datum/job/job = GetJob("AI")
if(!job)
@@ -202,7 +206,7 @@ var/datum/subsystem/job/SSjob
var/list/candidates = list()
candidates = FindOccupationCandidates(job, level)
if(candidates.len)
var/mob/new_player/candidate = pick(candidates)
var/mob/dead/new_player/candidate = pick(candidates)
if(AssignRole(candidate, "AI"))
ai_selected++
break
@@ -215,7 +219,7 @@ var/datum/subsystem/job/SSjob
* fills var "assigned_role" for all ready players.
* This proc must not have any side effect besides of modifying "assigned_role".
**/
/datum/subsystem/job/proc/DivideOccupations()
/datum/controller/subsystem/job/proc/DivideOccupations()
//Setup new player list and get the jobs list
Debug("Running DO")
@@ -226,7 +230,7 @@ var/datum/subsystem/job/SSjob
A.spawn_positions = 3
//Get the players who are ready
for(var/mob/new_player/player in player_list)
for(var/mob/dead/new_player/player in player_list)
if(player.ready && player.mind && !player.mind.assigned_role)
unassigned += player
@@ -256,7 +260,7 @@ var/datum/subsystem/job/SSjob
var/datum/job/assist = new /datum/job/assistant()
var/list/assistant_candidates = FindOccupationCandidates(assist, 3)
Debug("AC1, Candidates: [assistant_candidates.len]")
for(var/mob/new_player/player in assistant_candidates)
for(var/mob/dead/new_player/player in assistant_candidates)
Debug("AC1 pass, Player: [player]")
AssignRole(player, "Assistant")
assistant_candidates -= player
@@ -287,7 +291,7 @@ var/datum/subsystem/job/SSjob
CheckHeadPositions(level)
// Loop through all unassigned players
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(PopcapReached())
RejectPlayer(player)
@@ -325,13 +329,13 @@ var/datum/subsystem/job/SSjob
// 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/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(PopcapReached())
RejectPlayer(player)
else if(jobban_isbanned(player, "Assistant"))
GiveRandomJob(player) //you get to roll for random before everyone else just to be sure you don't get assistant. you're so speshul
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(PopcapReached())
RejectPlayer(player)
else if(player.client.prefs.joblessrole == BERANDOMJOB)
@@ -342,7 +346,7 @@ var/datum/subsystem/job/SSjob
Debug("DO, Running AC2")
// For those who wanted to be assistant if their preferences were filled, here you go.
for(var/mob/new_player/player in unassigned)
for(var/mob/dead/new_player/player in unassigned)
if(PopcapReached())
RejectPlayer(player)
if(player.client.prefs.joblessrole == BEASSISTANT)
@@ -351,13 +355,21 @@ var/datum/subsystem/job/SSjob
else // For those who don't want to play if their preference were filled, back you go.
RejectPlayer(player)
for(var/mob/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?)
for(var/mob/dead/new_player/player in unassigned) //Players that wanted to back out but couldn't because they're antags (can you feel the edge case?)
GiveRandomJob(player)
return 1
//Gives the player the stuff he should have with his rank
/datum/subsystem/job/proc/EquipRank(mob/living/H, rank, joined_late=0)
/datum/controller/subsystem/job/proc/EquipRank(mob/M, rank, joined_late=0)
var/mob/dead/new_player/N
var/mob/living/H
if(!joined_late)
N = M
H = N.new_character
else
H = M
var/datum/job/job = GetJob(rank)
H.job = rank
@@ -375,7 +387,7 @@ var/datum/subsystem/job/SSjob
break
if(!S) //if there isn't a spawnpoint send them to latejoin, if there's no latejoin go yell at your mapper
log_world("Couldn't find a round start spawn point for [rank]")
S = pick(latejoin)
S = get_turf(pick(latejoin))
if(!S) //final attempt, lets find some area in the arrivals shuttle to spawn them in to.
log_world("Couldn't find a round start latejoin spawn point.")
for(var/turf/T in get_area_turfs(/area/shuttle/arrival))
@@ -398,22 +410,26 @@ var/datum/subsystem/job/SSjob
var/new_mob = job.equip(H)
if(ismob(new_mob))
H = new_mob
if(!joined_late)
N.new_character = H
else
M = H
H << "<b>You are the [rank].</b>"
H << "<b>As the [rank] you answer directly to [job.supervisors]. Special circumstances may change this.</b>"
H << "<b>To speak on your departments radio, use the :h button. To see others, look closely at your headset.</b>"
to_chat(M, "<b>You are the [rank].</b>")
to_chat(M, "<b>As the [rank] you answer directly to [job.supervisors]. Special circumstances may change this.</b>")
to_chat(M, "<b>To speak on your departments radio, use the :h button. To see others, look closely at your headset.</b>")
if(job.req_admin_notify)
H << "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>"
to_chat(M, "<b>You are playing a job that is important for Game Progression. If you have to disconnect, please notify the admins via adminhelp.</b>")
if(config.minimal_access_threshold)
H << "<FONT color='blue'><B>As this station was initially staffed with a [config.jobs_have_minimal_access ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.</B></font>"
to_chat(M, "<FONT color='blue'><B>As this station was initially staffed with a [config.jobs_have_minimal_access ? "full crew, only your job's necessities" : "skeleton crew, additional access may"] have been added to your ID card.</B></font>")
if(job && H)
job.after_spawn(H)
job.after_spawn(H, M)
return H
/datum/subsystem/job/proc/setup_officer_positions()
/datum/controller/subsystem/job/proc/setup_officer_positions()
var/datum/job/J = SSjob.GetJob("Security Officer")
if(!J)
throw EXCEPTION("setup_officer_positions(): Security officer job is missing")
@@ -438,7 +454,7 @@ var/datum/subsystem/job/SSjob
break
/datum/subsystem/job/proc/LoadJobs()
/datum/controller/subsystem/job/proc/LoadJobs()
var/jobstext = return_file_text("config/jobs.txt")
for(var/datum/job/J in occupations)
var/regex/jobs = new("[J.title]=(-1|\\d+),(-1|\\d+)")
@@ -446,7 +462,7 @@ var/datum/subsystem/job/SSjob
J.total_positions = text2num(jobs.group[1])
J.spawn_positions = text2num(jobs.group[2])
/datum/subsystem/job/proc/HandleFeedbackGathering()
/datum/controller/subsystem/job/proc/HandleFeedbackGathering()
for(var/datum/job/job in occupations)
var/tmp_str = "|[job.title]|"
@@ -456,7 +472,7 @@ var/datum/subsystem/job/SSjob
var/level4 = 0 //never
var/level5 = 0 //banned
var/level6 = 0 //account too young
for(var/mob/new_player/player in player_list)
for(var/mob/dead/new_player/player in player_list)
if(!(player.ready && player.mind && !player.mind.assigned_role))
continue //This player is not ready
if(jobban_isbanned(player, job.title))
@@ -476,31 +492,34 @@ var/datum/subsystem/job/SSjob
tmp_str += "HIGH=[level1]|MEDIUM=[level2]|LOW=[level3]|NEVER=[level4]|BANNED=[level5]|YOUNG=[level6]|-"
feedback_add_details("job_preferences",tmp_str)
/datum/subsystem/job/proc/PopcapReached()
/datum/controller/subsystem/job/proc/PopcapReached()
if(config.hard_popcap || config.extreme_popcap)
var/relevent_cap = max(config.hard_popcap, config.extreme_popcap)
if((initial_players_to_assign - unassigned.len) >= relevent_cap)
return 1
return 0
/datum/subsystem/job/proc/RejectPlayer(mob/new_player/player)
/datum/controller/subsystem/job/proc/RejectPlayer(mob/dead/new_player/player)
if(player.mind && player.mind.special_role)
return
if(PopcapReached())
Debug("Popcap overflow Check observer located, Player: [player]")
player << "<b>You have failed to qualify for any job you desired.</b>"
to_chat(player, "<b>You have failed to qualify for any job you desired.</b>")
unassigned -= player
player.ready = 0
/datum/subsystem/job/Recover()
/datum/controller/subsystem/job/Recover()
set waitfor = FALSE
var/oldjobs = SSjob.occupations
spawn(20)
for (var/datum/job/J in oldjobs)
spawn(-1)
var/datum/job/newjob = GetJob(J.title)
if (!istype(newjob))
return
newjob.total_positions = J.total_positions
newjob.spawn_positions = J.spawn_positions
newjob.current_positions = J.current_positions
sleep(20)
for (var/datum/job/J in oldjobs)
INVOKE_ASYNC(src, .proc/RecoverJob, J)
/datum/controller/subsystem/job/proc/RecoverJob(datum/job/J)
var/datum/job/newjob = GetJob(J.title)
if (!istype(newjob))
return
newjob.total_positions = J.total_positions
newjob.spawn_positions = J.spawn_positions
newjob.current_positions = J.current_positions
+82 -96
View File
@@ -1,119 +1,105 @@
var/datum/subsystem/lighting/SSlighting
var/datum/controller/subsystem/lighting/SSlighting
#define SSLIGHTING_LIGHTS 1
#define SSLIGHTING_TURFS 2
var/list/lighting_update_lights = list() // List of lighting sources queued for update.
var/list/lighting_update_corners = list() // List of lighting corners queued for update.
var/list/lighting_update_objects = list() // List of lighting objects queued for update.
/datum/subsystem/lighting
/datum/controller/subsystem/lighting
name = "Lighting"
init_order = 1
wait = 1
wait = 2
init_order = -20
flags = SS_TICKER
priority = 25
display_order = 5
var/list/changed_lights = list() //list of all datum/light_source that need updating
var/changed_lights_workload = 0 //stats on the largest number of lights (max changed_lights.len)
var/list/changed_turfs = list() //list of all turfs which may have a different light level
var/changed_turfs_workload = 0 //stats on the largest number of turfs changed (max changed_turfs.len)
var/initialized = FALSE
/datum/subsystem/lighting/New()
/datum/controller/subsystem/lighting/New()
NEW_SS_GLOBAL(SSlighting)
return ..()
/datum/subsystem/lighting/stat_entry()
..("L:[round(changed_lights_workload,1)]|T:[round(changed_turfs_workload,1)]")
/datum/controller/subsystem/lighting/stat_entry()
..("L:[lighting_update_lights.len]|C:[lighting_update_corners.len]|O:[lighting_update_objects.len]")
//Workhorse of lighting. It cycles through each light that needs updating. It updates their
//effects and then processes every turf in the queue, updating their lighting object's appearance
//Any light that returns 1 in check() deletes itself
//By using queues we are ensuring we don't perform more updates than are necessary
/datum/subsystem/lighting/fire(resumed = 0)
var/ticklimit = CURRENT_TICKLIMIT
//split our tick allotment in half so we don't spend it all on lightshift checks
CURRENT_TICKLIMIT = world.tick_usage + ((ticklimit-world.tick_usage)/2)
var/list/changed_lights = src.changed_lights
if (!resumed)
changed_lights_workload = MC_AVERAGE(changed_lights_workload, changed_lights.len)
var/i = 1
while (i <= changed_lights.len)
var/datum/light_source/LS = changed_lights[i++]
LS.check()
if (MC_TICK_CHECK)
break
if (i > 1)
changed_lights.Cut(1,i)
CURRENT_TICKLIMIT = ticklimit
var/list/changed_turfs = src.changed_turfs
if (!resumed)
changed_turfs_workload = MC_AVERAGE(changed_turfs_workload, changed_turfs.len)
i = 1
while (i <= changed_turfs.len)
var/turf/T = changed_turfs[i++]
if(T.lighting_changed)
T.redraw_lighting()
if (MC_TICK_CHECK)
break
if (i > 1)
changed_turfs.Cut(1,i)
//same as above except it attempts to shift ALL turfs in the world regardless of lighting_changed status
/datum/subsystem/lighting/Initialize(timeofday)
var/list/turfs_to_init = block(locate(1, 1, 1), locate(world.maxx, world.maxy, world.maxz))
/datum/controller/subsystem/lighting/Initialize(timeofday)
if (config.starlight)
for(var/area/A in world)
if (A.lighting_use_dynamic == DYNAMIC_LIGHTING_IFSTARLIGHT)
if (A.dynamic_lighting == DYNAMIC_LIGHTING_IFSTARLIGHT)
A.luminosity = 0
CHECK_TICK
for(var/thing in changed_lights)
var/datum/light_source/LS = thing
LS.check()
CHECK_TICK
changed_lights.Cut()
create_all_lighting_objects()
initialized = TRUE
for(var/thing in turfs_to_init)
var/turf/T = thing
T.init_lighting()
CHECK_TICK
changed_turfs.Cut()
fire(FALSE, TRUE)
..()
//Used to strip valid information from an existing instance and transfer it to the replacement. i.e. when a crash occurs
//It works by using spawn(-1) to transfer the data, if there is a runtime the data does not get transfered but the loop
//does not crash
/datum/subsystem/lighting/Recover()
if(!istype(SSlighting.changed_turfs))
SSlighting.changed_turfs = list()
if(!istype(SSlighting.changed_lights))
SSlighting.changed_lights = list()
/datum/controller/subsystem/lighting/fire(resumed, init_tick_checks)
var/real_tick_limit
if(!init_tick_checks)
real_tick_limit = CURRENT_TICKLIMIT
CURRENT_TICKLIMIT = ((real_tick_limit - world.tick_usage) / 3) + world.tick_usage
var/i = 0
for (i in 1 to lighting_update_lights.len)
var/datum/light_source/L = lighting_update_lights[i]
for(var/thing in SSlighting.changed_lights)
var/datum/light_source/LS = thing
spawn(-1) //so we don't crash the loop (inefficient)
LS.check()
if (L.check() || L.destroyed || L.force_update)
L.remove_lum()
if (!L.destroyed)
L.apply_lum()
for(var/thing in changed_turfs)
var/turf/T = thing
if(T.lighting_changed)
spawn(-1)
T.redraw_lighting()
else if (L.vis_update) //We smartly update only tiles that became (in) visible to use.
L.smart_vis_update()
var/msg = "## DEBUG: [time2text(world.timeofday)] [name] subsystem restarted. Reports:\n"
for(var/varname in SSlighting.vars)
switch(varname)
if("tag","bestF","type","parent_type","vars")
continue
else
var/varval1 = SSlighting.vars[varname]
var/varval2 = vars[varname]
if(istype(varval1,/list))
varval1 = "/list([length(varval1)])"
varval2 = "/list([length(varval2)])"
msg += "\t [varname] = [varval1] -> [varval2]\n"
log_world(msg)
L.vis_update = FALSE
L.force_update = FALSE
L.needs_update = FALSE
if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (i)
lighting_update_lights.Cut(1, i+1)
i = 0
if(!init_tick_checks)
CURRENT_TICKLIMIT = ((real_tick_limit - world.tick_usage)/2)+world.tick_usage
for (i in 1 to lighting_update_corners.len)
var/datum/lighting_corner/C = lighting_update_corners[i]
C.update_objects()
C.needs_update = FALSE
if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (i)
lighting_update_corners.Cut(1, i+1)
i = 0
if(!init_tick_checks)
CURRENT_TICKLIMIT = real_tick_limit
for (i in 1 to lighting_update_objects.len)
var/atom/movable/lighting_object/O = lighting_update_objects[i]
if (QDELETED(O))
continue
O.update()
O.needs_update = FALSE
if(init_tick_checks)
CHECK_TICK
else if (MC_TICK_CHECK)
break
if (i)
lighting_update_objects.Cut(1, i+1)
/datum/controller/subsystem/lighting/Recover()
initialized = SSlighting.initialized
..()
+9 -10
View File
@@ -1,21 +1,20 @@
var/datum/subsystem/machines/SSmachine
var/datum/controller/subsystem/machines/SSmachine
/datum/subsystem/machines
/datum/controller/subsystem/machines
name = "Machines"
init_order = 9
display_order = 3
flags = SS_KEEP_TIMING
var/list/processing = list()
var/list/currentrun = list()
var/list/powernets = list()
/datum/subsystem/machines/Initialize()
/datum/controller/subsystem/machines/Initialize()
makepowernets()
fire()
..()
/datum/subsystem/machines/proc/makepowernets()
/datum/controller/subsystem/machines/proc/makepowernets()
for(var/datum/powernet/PN in powernets)
qdel(PN)
powernets.Cut()
@@ -26,15 +25,15 @@ var/datum/subsystem/machines/SSmachine
NewPN.add_cable(PC)
propagate_network(PC,PC.powernet)
/datum/subsystem/machines/New()
/datum/controller/subsystem/machines/New()
NEW_SS_GLOBAL(SSmachine)
/datum/subsystem/machines/stat_entry()
/datum/controller/subsystem/machines/stat_entry()
..("M:[processing.len]|PN:[powernets.len]")
/datum/subsystem/machines/fire(resumed = 0)
/datum/controller/subsystem/machines/fire(resumed = 0)
if (!resumed)
for(var/datum/powernet/Powernet in powernets)
Powernet.reset() //reset the power state.
@@ -57,7 +56,7 @@ var/datum/subsystem/machines/SSmachine
if (MC_TICK_CHECK)
return
/datum/subsystem/machines/proc/setup_template_powernets(list/cables)
/datum/controller/subsystem/machines/proc/setup_template_powernets(list/cables)
for(var/A in cables)
var/obj/structure/cable/PC = A
if(!PC.powernet)
@@ -65,7 +64,7 @@ var/datum/subsystem/machines/SSmachine
NewPN.add_cable(PC)
propagate_network(PC,PC.powernet)
/datum/subsystem/machines/Recover()
/datum/controller/subsystem/machines/Recover()
if (istype(SSmachine.processing))
processing = SSmachine.processing
if (istype(SSmachine.powernets))
+143 -21
View File
@@ -1,14 +1,17 @@
var/datum/subsystem/mapping/SSmapping
var/datum/controller/subsystem/mapping/SSmapping
/datum/subsystem/mapping
/datum/controller/subsystem/mapping
name = "Mapping"
init_order = 12
flags = SS_NO_FIRE
display_order = 50
var/list/nuke_tiles = list()
var/list/nuke_threats = list()
var/datum/map_config/previous_map_config
var/datum/map_config/config
var/datum/map_config/next_map_config
var/list/map_templates = list()
var/list/ruins_templates = list()
@@ -18,20 +21,35 @@ var/datum/subsystem/mapping/SSmapping
var/list/shuttle_templates = list()
var/list/shelter_templates = list()
/datum/subsystem/mapping/New()
/datum/controller/subsystem/mapping/New()
NEW_SS_GLOBAL(SSmapping)
if(!previous_map_config)
previous_map_config = new("data/previous_map.json", delete_after = TRUE)
if(previous_map_config.defaulted)
previous_map_config = null
if(!config)
#ifdef FORCE_MAP
config = new(FORCE_MAP)
#else
config = new
#endif
return ..()
/datum/subsystem/mapping/Initialize(timeofday)
/datum/controller/subsystem/mapping/Initialize(timeofday)
if(config.defaulted)
to_chat(world, "<span class='boldannounce'>Unable to load next map config, defaulting to Box Station</span>")
loadWorld()
SortAreas()
process_teleport_locs() //Sets up the wizard teleport locations
preloadTemplates()
// Pick a random away mission.
createRandomZlevel()
// Generate mining.
var/mining_type = MINETYPE
var/mining_type = config.minetype
if (mining_type == "lavaland")
seedRuins(list(5), config.lavaland_budget, /area/lavaland/surface/outdoors, lava_ruins_templates)
seedRuins(list(5), global.config.lavaland_budget, /area/lavaland/surface/outdoors, lava_ruins_templates)
spawn_rivers()
// deep space ruins
@@ -43,7 +61,7 @@ var/datum/subsystem/mapping/SSmapping
else
space_zlevels += i
seedRuins(space_zlevels, config.space_budget, /area/space, space_ruins_templates)
seedRuins(space_zlevels, global.config.space_budget, /area/space, space_ruins_templates)
// Set up Z-level transistions.
setup_map_transitions()
@@ -53,26 +71,24 @@ var/datum/subsystem/mapping/SSmapping
Used by the AI doomsday and the self destruct nuke.
*/
/datum/subsystem/mapping/proc/add_nuke_threat(datum/nuke)
/datum/controller/subsystem/mapping/proc/add_nuke_threat(datum/nuke)
nuke_threats[nuke] = TRUE
check_nuke_threats()
/datum/subsystem/mapping/proc/remove_nuke_threat(datum/nuke)
/datum/controller/subsystem/mapping/proc/remove_nuke_threat(datum/nuke)
nuke_threats -= nuke
check_nuke_threats()
/datum/subsystem/mapping/proc/check_nuke_threats()
/datum/controller/subsystem/mapping/proc/check_nuke_threats()
for(var/datum/d in nuke_threats)
if(!istype(d) || QDELETED(d))
nuke_threats -= d
var/threats = nuke_threats.len
for(var/N in nuke_tiles)
var/turf/open/floor/T = N
T.icon_state = (threats ? "rcircuitanim" : T.icon_regular_floor)
var/turf/open/floor/circuit/C = N
C.update_icon()
/datum/subsystem/mapping/Recover()
/datum/controller/subsystem/mapping/Recover()
flags |= SS_NO_INIT
map_templates = SSmapping.map_templates
ruins_templates = SSmapping.ruins_templates
@@ -81,7 +97,113 @@ var/datum/subsystem/mapping/SSmapping
shuttle_templates = SSmapping.shuttle_templates
shelter_templates = SSmapping.shelter_templates
/datum/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup
previous_map_config = SSmapping.previous_map_config
config = SSmapping.config
next_map_config = SSmapping.next_map_config
/datum/controller/subsystem/mapping/proc/TryLoadZ(filename, errorList, forceLevel, last)
var/static/dmm_suite/loader
if(!loader)
loader = new
if(!loader.load_map(file(filename), 0, 0, forceLevel, no_changeturf = TRUE))
errorList |= filename
if(last)
QDEL_NULL(loader)
/datum/controller/subsystem/mapping/proc/CreateSpace(zlevel)
while(world.maxz < zlevel)
CHECK_TICK
++world.maxz
CHECK_TICK
for(var/T in block(locate(1, 1, zlevel), locate(world.maxx, world.maxy, zlevel)))
CHECK_TICK
new /turf/open/space(T)
#define INIT_ANNOUNCE(X) to_chat(world, "<span class='boldannounce'>[X]</span>"); log_world(X)
/datum/controller/subsystem/mapping/proc/loadWorld()
//if any of these fail, something has gone horribly, HORRIBLY, wrong
var/list/FailedZs = list()
var/start_time = REALTIMEOFDAY
INIT_ANNOUNCE("Loading [config.map_name]...")
TryLoadZ(config.GetFullMapPath(), FailedZs, ZLEVEL_STATION)
INIT_ANNOUNCE("Loaded station in [(REALTIMEOFDAY - start_time)/10]s!")
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!")
for(var/I in (world.maxz + 1) to ZLEVEL_SPACEMAX)
CreateSpace(I)
if(LAZYLEN(FailedZs)) //but seriously, unless the server's filesystem is messed up this will never happen
var/msg = "RED ALERT! The following map files failed to load: [FailedZs[1]]"
if(FailedZs.len > 1)
for(var/I in 2 to FailedZs.len)
msg += ", [I]"
msg += ". Yell at your server host!"
INIT_ANNOUNCE(msg)
#undef INIT_ANNOUNCE
/datum/controller/subsystem/mapping/proc/maprotate()
var/players = clients.len
var/list/mapvotes = list()
//count votes
if(global.config.allow_map_voting)
for (var/client/c in clients)
var/vote = c.prefs.preferred_map
if (!vote)
if (global.config.defaultmap)
mapvotes[global.config.defaultmap.map_name] += 1
continue
mapvotes[vote] += 1
//filter votes
for (var/map in mapvotes)
if (!map)
mapvotes.Remove(map)
if (!(map in global.config.maplist))
mapvotes.Remove(map)
continue
var/datum/map_config/VM = global.config.maplist[map]
if (!VM)
mapvotes.Remove(map)
continue
if (VM.voteweight <= 0)
mapvotes.Remove(map)
continue
if (VM.config_min_users > 0 && players < VM.config_min_users)
mapvotes.Remove(map)
continue
if (VM.config_max_users > 0 && players > VM.config_max_users)
mapvotes.Remove(map)
continue
mapvotes[map] = mapvotes[map]*VM.voteweight
var/pickedmap = global.config.allow_map_voting ? pickweight(mapvotes) : pick(global.config.maplist)
if (!pickedmap)
return
var/datum/map_config/VM = global.config.maplist[pickedmap]
message_admins("Randomly rotating map to [VM.map_name]")
. = changemap(VM)
if (. && VM.map_name != config.map_name)
to_chat(world, "<span class='boldannounce'>Map rotation has chosen [VM.map_name] for next round!</span>")
/datum/controller/subsystem/mapping/proc/changemap(var/datum/map_config/VM)
if(!VM.MakeNextMap())
next_map_config = new(default_to_box = TRUE)
message_admins("Failed to set new map with next_map.json for [VM.map_name]! Using default as backup!")
return
next_map_config = VM
return TRUE
/datum/controller/subsystem/mapping/Shutdown()
if(config)
config.MakePreviousMap()
/datum/controller/subsystem/mapping/proc/preloadTemplates(path = "_maps/templates/") //see master controller setup
var/list/filelist = flist(path)
for(var/map in filelist)
var/datum/map_template/T = new(path = "[path][map]", rename = "[map]")
@@ -91,7 +213,7 @@ var/datum/subsystem/mapping/SSmapping
preloadShuttleTemplates()
preloadShelterTemplates()
/datum/subsystem/mapping/proc/preloadRuinTemplates()
/datum/controller/subsystem/mapping/proc/preloadRuinTemplates()
// Still supporting bans by filename
var/list/banned = generateMapList("config/lavaruinblacklist.txt")
banned += generateMapList("config/spaceruinblacklist.txt")
@@ -114,7 +236,7 @@ var/datum/subsystem/mapping/SSmapping
else if(istype(R, /datum/map_template/ruin/space))
space_ruins_templates[R.name] = R
/datum/subsystem/mapping/proc/preloadShuttleTemplates()
/datum/controller/subsystem/mapping/proc/preloadShuttleTemplates()
var/list/unbuyable = generateMapList("config/unbuyableshuttles.txt")
for(var/item in subtypesof(/datum/map_template/shuttle))
@@ -129,7 +251,7 @@ var/datum/subsystem/mapping/SSmapping
shuttle_templates[S.shuttle_id] = S
map_templates[S.shuttle_id] = S
/datum/subsystem/mapping/proc/preloadShelterTemplates()
/datum/controller/subsystem/mapping/proc/preloadShelterTemplates()
for(var/item in subtypesof(/datum/map_template/shelter))
var/datum/map_template/shelter/shelter_type = item
if(!(initial(shelter_type.mappath)))
@@ -137,4 +259,4 @@ var/datum/subsystem/mapping/SSmapping
var/datum/map_template/shelter/S = new shelter_type()
shelter_templates[S.shelter_id] = S
map_templates[S.shelter_id] = S
map_templates[S.shelter_id] = S
+20 -20
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/minimap/SSminimap
var/datum/controller/subsystem/minimap/SSminimap
/datum/subsystem/minimap
/datum/controller/subsystem/minimap
name = "Minimap"
init_order = -2
flags = SS_NO_FIRE
@@ -9,11 +9,11 @@ var/datum/subsystem/minimap/SSminimap
var/list/z_levels = list(ZLEVEL_STATION)
/datum/subsystem/minimap/New()
/datum/controller/subsystem/minimap/New()
NEW_SS_GLOBAL(SSminimap)
/datum/subsystem/minimap/Initialize(timeofday)
var/hash = md5(file2text("_maps/[MAP_PATH]/[MAP_FILE]"))
/datum/controller/subsystem/minimap/Initialize(timeofday)
var/hash = md5(SSmapping.config.GetFullMapPath())
if(config.generate_minimaps)
if(hash == trim(file2text(hash_path())))
for(var/z in z_levels) //We have these files cached, let's register them
@@ -25,48 +25,48 @@ var/datum/subsystem/minimap/SSminimap
fdel(hash_path())
text2file(hash, hash_path())
else
world << "<span class='boldannounce'>Minimap generation disabled. Loading from cache...</span>"
to_chat(world, "<span class='boldannounce'>Minimap generation disabled. Loading from cache...</span>")
var/fileloc = 0
if(check_files(0)) //Let's first check if we have maps cached in the data folder. NOTE: This will override the backup files even if this map is older.
if(hash != trim(file2text(hash_path())))
world << "<span class='boldannounce'>Loaded cached minimap is outdated. There may be minor discrepancies in layout.</span>" //Disclaimer against players saying map is wrong.
to_chat(world, "<span class='boldannounce'>Loaded cached minimap is outdated. There may be minor discrepancies in layout.</span>" )
fileloc = 0
else
if(!check_files(1))
world << "<span class='boldannounce'>Failed to load backup minimap file. Aborting.</span>" //We couldn't find something. Bail to prevent issues with null files
to_chat(world, "<span class='boldannounce'>Failed to load backup minimap file. Aborting.</span>" )
return
fileloc = 1 //No map image cached with the current map, and we have a backup. Let's fall back to it.
world << "<span class='boldannounce'>No cached minimaps detected. Backup files loaded.</span>"
to_chat(world, "<span class='boldannounce'>No cached minimaps detected. Backup files loaded.</span>")
for(var/z in z_levels)
register_asset("minimap_[z].png", fcopy_rsc(map_path(z,fileloc)))
..()
/datum/subsystem/minimap/proc/check_files(backup) // If the backup argument is true, looks in the icons folder. If false looks in the data folder.
/datum/controller/subsystem/minimap/proc/check_files(backup) // If the backup argument is true, looks in the icons folder. If false looks in the data folder.
for(var/z in z_levels)
if(!fexists(file(map_path(z,backup)))) //Let's make sure we have a file for this map
if(backup)
log_world("Failed to find backup file for map [MAP_NAME] on zlevel [z].")
log_world("Failed to find backup file for map [SSmapping.config.map_name] on zlevel [z].")
return FALSE
return TRUE
/datum/subsystem/minimap/proc/hash_path(backup)
/datum/controller/subsystem/minimap/proc/hash_path(backup)
if(backup)
return "icons/minimaps/[MAP_NAME].md5"
return "icons/minimaps/[SSmapping.config.map_name].md5"
else
return "data/minimaps/[MAP_NAME].md5"
return "data/minimaps/[SSmapping.config.map_name].md5"
/datum/subsystem/minimap/proc/map_path(z,backup)
/datum/controller/subsystem/minimap/proc/map_path(z,backup)
if(backup)
return "icons/minimaps/[MAP_NAME]_[z].png"
return "icons/minimaps/[SSmapping.config.map_name]_[z].png"
else
return "data/minimaps/[MAP_NAME]_[z].png"
return "data/minimaps/[SSmapping.config.map_name]_[z].png"
/datum/subsystem/minimap/proc/send(client/client)
/datum/controller/subsystem/minimap/proc/send(client/client)
for(var/z in z_levels)
send_asset(client, "minimap_[z].png")
/datum/subsystem/minimap/proc/generate(z = 1, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
/datum/controller/subsystem/minimap/proc/generate(z = 1, x1 = 1, y1 = 1, x2 = world.maxx, y2 = world.maxy)
// Load the background.
var/icon/minimap = new /icon('icons/minimap.dmi')
// Scale it up to our target size.
@@ -81,7 +81,7 @@ var/datum/subsystem/minimap/SSminimap
final.Insert(minimap, "", SOUTH, 1, 0)
fcopy(final, map_path(z))
/datum/subsystem/minimap/proc/generate_tile(turf/tile, icon/minimap)
/datum/controller/subsystem/minimap/proc/generate_tile(turf/tile, icon/minimap)
var/icon/tile_icon
var/obj/obj
var/list/obj_icons
+5 -6
View File
@@ -1,23 +1,22 @@
var/datum/subsystem/mobs/SSmob
var/datum/controller/subsystem/mobs/SSmob
/datum/subsystem/mobs
/datum/controller/subsystem/mobs
name = "Mobs"
init_order = 4
display_order = 4
priority = 100
flags = SS_KEEP_TIMING|SS_NO_INIT
var/list/currentrun = list()
/datum/subsystem/mobs/New()
/datum/controller/subsystem/mobs/New()
NEW_SS_GLOBAL(SSmob)
/datum/subsystem/mobs/stat_entry()
/datum/controller/subsystem/mobs/stat_entry()
..("P:[mob_list.len]")
/datum/subsystem/mobs/fire(resumed = 0)
/datum/controller/subsystem/mobs/fire(resumed = 0)
var/seconds = wait * 0.1
if (!resumed)
src.currentrun = mob_list.Copy()
+8 -9
View File
@@ -1,9 +1,8 @@
var/datum/subsystem/npcpool/SSnpc
var/datum/controller/subsystem/npcpool/SSnpc
/datum/subsystem/npcpool
/datum/controller/subsystem/npcpool
name = "NPC Pool"
init_order = 17
display_order = 6
flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_NO_TICK_CHECK
priority = 25
@@ -15,18 +14,18 @@ var/datum/subsystem/npcpool/SSnpc
var/list/botPool_l = list() //list of all npcs using the pool
var/list/botPool_l_non = list() //list of all non SNPC mobs using the pool
/datum/subsystem/npcpool/proc/insertBot(toInsert)
/datum/controller/subsystem/npcpool/proc/insertBot(toInsert)
if(istype(toInsert,/mob/living/carbon/human/interactive))
botPool_l |= toInsert
/datum/subsystem/npcpool/New()
/datum/controller/subsystem/npcpool/New()
NEW_SS_GLOBAL(SSnpc)
/datum/subsystem/npcpool/stat_entry()
/datum/controller/subsystem/npcpool/stat_entry()
..("T:[botPool_l.len + botPool_l_non.len]|D:[needsDelegate.len]|A:[needsAssistant.len + needsHelp_non.len]|U:[canBeUsed.len + canBeUsed_non.len]")
/datum/subsystem/npcpool/proc/cleanNull()
/datum/controller/subsystem/npcpool/proc/cleanNull()
//cleanup nulled bots
listclearnulls(botPool_l)
listclearnulls(needsDelegate)
@@ -34,7 +33,7 @@ var/datum/subsystem/npcpool/SSnpc
listclearnulls(needsAssistant)
/datum/subsystem/npcpool/fire()
/datum/controller/subsystem/npcpool/fire()
//bot delegation and coordination systems
//General checklist/Tasks for delegating a task or coordinating it (for SNPCs)
// 1. Bot proximity to task target: if too far, delegate, if close, coordinate
@@ -121,7 +120,7 @@ var/datum/subsystem/npcpool/SSnpc
candidate.update_icons()
npcCount++
/datum/subsystem/npcpool/Recover()
/datum/controller/subsystem/npcpool/Recover()
if (istype(SSnpc.botPool_l))
botPool_l = SSnpc.botPool_l
if (istype(SSnpc.botPool_l_non))
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/orbit/SSorbit
var/datum/controller/subsystem/orbit/SSorbit
/datum/subsystem/orbit
/datum/controller/subsystem/orbit
name = "Orbits"
priority = 35
wait = 2
@@ -9,15 +9,15 @@ var/datum/subsystem/orbit/SSorbit
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/orbit/New()
/datum/controller/subsystem/orbit/New()
NEW_SS_GLOBAL(SSorbit)
/datum/subsystem/orbit/stat_entry()
/datum/controller/subsystem/orbit/stat_entry()
..("P:[processing.len]")
/datum/subsystem/orbit/fire(resumed = 0)
/datum/controller/subsystem/orbit/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+9 -9
View File
@@ -1,7 +1,7 @@
var/datum/subsystem/pai/SSpai
var/datum/controller/subsystem/pai/SSpai
var/list/obj/item/device/paicard/pai_card_list = list()
/datum/subsystem/pai
/datum/controller/subsystem/pai
name = "pAI"
flags = SS_NO_INIT|SS_NO_FIRE
@@ -10,10 +10,10 @@ var/list/obj/item/device/paicard/pai_card_list = list()
var/ghost_spam = FALSE
var/spam_delay = 100
/datum/subsystem/pai/New()
/datum/controller/subsystem/pai/New()
NEW_SS_GLOBAL(SSpai)
/datum/subsystem/pai/Topic(href, href_list[])
/datum/controller/subsystem/pai/Topic(href, href_list[])
if(href_list["download"])
var/datum/paiCandidate/candidate = locate(href_list["candidate"])
var/obj/item/device/paicard/card = locate(href_list["device"])
@@ -84,7 +84,7 @@ var/list/obj/item/device/paicard/pai_card_list = list()
return
recruitWindow(usr)
/datum/subsystem/pai/proc/recruitWindow(mob/M)
/datum/controller/subsystem/pai/proc/recruitWindow(mob/M)
var/datum/paiCandidate/candidate
for(var/datum/paiCandidate/c in candidates)
if(c.key == M.key)
@@ -135,10 +135,10 @@ var/list/obj/item/device/paicard/pai_card_list = list()
M << browse(dat, "window=paiRecruit")
/datum/subsystem/pai/proc/spam_again()
/datum/controller/subsystem/pai/proc/spam_again()
ghost_spam = FALSE
/datum/subsystem/pai/proc/check_ready(var/datum/paiCandidate/C)
/datum/controller/subsystem/pai/proc/check_ready(var/datum/paiCandidate/C)
if(!C.ready)
return FALSE
for(var/mob/dead/observer/O in player_list)
@@ -146,7 +146,7 @@ var/list/obj/item/device/paicard/pai_card_list = list()
return C
return FALSE
/datum/subsystem/pai/proc/findPAI(obj/item/device/paicard/p, mob/user)
/datum/controller/subsystem/pai/proc/findPAI(obj/item/device/paicard/p, mob/user)
if(!ghost_spam)
ghost_spam = TRUE
for(var/mob/dead/observer/G in player_list)
@@ -155,7 +155,7 @@ var/list/obj/item/device/paicard/pai_card_list = list()
if(!(ROLE_PAI in G.client.prefs.be_special))
continue
//G << 'sound/misc/server-ready.ogg' //Alerting them to their consideration
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'>Someone 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)
+6 -6
View File
@@ -1,17 +1,17 @@
var/datum/subsystem/parallax/SSparallax
var/datum/controller/subsystem/parallax/SSparallax
/datum/subsystem/parallax
name = "parallax"
/datum/controller/subsystem/parallax
name = "Parallax"
wait = 2
flags = SS_POST_FIRE_TIMING | SS_FIRE_IN_LOBBY | SS_BACKGROUND | SS_NO_INIT
priority = 65
var/list/currentrun
/datum/subsystem/parallax/New()
/datum/controller/subsystem/parallax/New()
NEW_SS_GLOBAL(SSparallax)
return ..()
/datum/subsystem/parallax/fire(resumed = 0)
/datum/controller/subsystem/parallax/fire(resumed = 0)
if (!resumed)
src.currentrun = clients.Copy()
@@ -39,4 +39,4 @@ var/datum/subsystem/parallax/SSparallax
C.movingmob = A
if (MC_TICK_CHECK)
return
currentrun = null
currentrun = null
+17 -17
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/persistence/SSpersistence
var/datum/controller/subsystem/persistence/SSpersistence
/datum/subsystem/persistence
/datum/controller/subsystem/persistence
name = "Persistence"
init_order = -100
flags = SS_NO_FIRE
@@ -13,19 +13,19 @@ var/datum/subsystem/persistence/SSpersistence
var/list/saved_messages = list()
var/savefile/chisel_messages_sav
/datum/subsystem/persistence/New()
/datum/controller/subsystem/persistence/New()
NEW_SS_GLOBAL(SSpersistence)
/datum/subsystem/persistence/Initialize()
/datum/controller/subsystem/persistence/Initialize()
LoadSatchels()
LoadPoly()
LoadChiselMessages()
..()
/datum/subsystem/persistence/proc/LoadSatchels()
/datum/controller/subsystem/persistence/proc/LoadSatchels()
secret_satchels = new /savefile("data/npc_saves/SecretSatchels.sav")
satchel_blacklist = typecacheof(list(/obj/item/stack/tile/plasteel, /obj/item/weapon/crowbar))
secret_satchels[MAP_NAME] >> old_secret_satchels
secret_satchels[SSmapping.config.map_name] >> old_secret_satchels
var/list/expanded_old_satchels = list()
var/placed_satchels = 0
@@ -44,14 +44,14 @@ var/datum/subsystem/persistence/SSpersistence
if(!isemptylist(free_satchels) && ((free_satchels.len + placed_satchels) >= (50 - expanded_old_satchels.len) * 0.1)) //up to six tiles, more than enough to kill anything that moves
break
/datum/subsystem/persistence/proc/PlaceSecretSatchel(list/expanded_old_satchels)
/datum/controller/subsystem/persistence/proc/PlaceSecretSatchel(list/expanded_old_satchels)
var/satchel_string
if(expanded_old_satchels.len >= 20) //guards against low drop pools assuring that one player cannot reliably find his own gear.
satchel_string = pick_n_take(expanded_old_satchels)
old_secret_satchels = jointext(expanded_old_satchels,"#")
secret_satchels[MAP_NAME] << old_secret_satchels
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
var/list/chosen_satchel = splittext(satchel_string,"|")
if(!chosen_satchel || isemptylist(chosen_satchel) || chosen_satchel.len != 3) //Malformed
@@ -70,15 +70,15 @@ var/datum/subsystem/persistence/SSpersistence
new path(F)
return 1
/datum/subsystem/persistence/proc/LoadPoly()
/datum/controller/subsystem/persistence/proc/LoadPoly()
for(var/mob/living/simple_animal/parrot/Poly/P in living_mob_list)
twitterize(P.speech_buffer, "polytalk")
break //Who's been duping the bird?!
/datum/subsystem/persistence/proc/LoadChiselMessages()
/datum/controller/subsystem/persistence/proc/LoadChiselMessages()
chisel_messages_sav = new /savefile("data/npc_saves/ChiselMessages.sav")
var/saved_json
chisel_messages_sav[MAP_NAME] >> saved_json
chisel_messages_sav[SSmapping.config.map_name] >> saved_json
if(!saved_json)
return
@@ -98,11 +98,11 @@ var/datum/subsystem/persistence/SSpersistence
qdel(M)
/datum/subsystem/persistence/proc/CollectData()
/datum/controller/subsystem/persistence/proc/CollectData()
CollectChiselMessages()
CollectSecretSatchels()
/datum/subsystem/persistence/proc/CollectSecretSatchels()
/datum/controller/subsystem/persistence/proc/CollectSecretSatchels()
for(var/A in new_secret_satchels)
var/obj/item/weapon/storage/backpack/satchel/flat/F = A
if(QDELETED(F) || F.z != ZLEVEL_STATION || F.invisibility != INVISIBILITY_MAXIMUM)
@@ -118,13 +118,13 @@ var/datum/subsystem/persistence/SSpersistence
if(isemptylist(savable_obj))
continue
old_secret_satchels += "[F.x]|[F.y]|[pick(savable_obj)]#"
secret_satchels[MAP_NAME] << old_secret_satchels
secret_satchels[SSmapping.config.map_name] << old_secret_satchels
/datum/subsystem/persistence/proc/CollectChiselMessages()
/datum/controller/subsystem/persistence/proc/CollectChiselMessages()
for(var/obj/structure/chisel_message/M in chisel_messages)
saved_messages += list(M.pack())
chisel_messages_sav[MAP_NAME] << json_encode(saved_messages)
chisel_messages_sav[SSmapping.config.map_name] << json_encode(saved_messages)
/datum/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
/datum/controller/subsystem/persistence/proc/SaveChiselMessage(obj/structure/chisel_message/M)
saved_messages += list(M.pack()) // dm eats one list.
+4 -4
View File
@@ -1,18 +1,18 @@
#define PING_BUFFER_TIME 25
var/datum/subsystem/ping/SSping
var/datum/controller/subsystem/ping/SSping
/datum/subsystem/ping
/datum/controller/subsystem/ping
name = "Ping"
wait = 6
flags = SS_NO_INIT|SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY
priority = 10
var/list/currentrun
/datum/subsystem/ping/New()
/datum/controller/subsystem/ping/New()
NEW_SS_GLOBAL(SSping)
/datum/subsystem/ping/fire(resumed = FALSE)
/datum/controller/subsystem/ping/fire(resumed = FALSE)
if (!resumed)
src.currentrun = clients.Copy()
@@ -1,10 +1,10 @@
//Fires five times every second.
var/datum/subsystem/processing/fastprocess/SSfastprocess
/datum/subsystem/processing/fastprocess
var/datum/controller/subsystem/processing/fastprocess/SSfastprocess
/datum/controller/subsystem/processing/fastprocess
name = "Fast Processing"
wait = 2
stat_tag = "FP"
/datum/subsystem/processing/fastprocess/New()
/datum/controller/subsystem/processing/fastprocess/New()
NEW_SS_GLOBAL(SSfastprocess)
@@ -1,11 +1,11 @@
var/datum/subsystem/processing/flightpacks/SSflightpacks
/datum/subsystem/processing/flightpacks
var/datum/controller/subsystem/processing/flightpacks/SSflightpacks
/datum/controller/subsystem/processing/flightpacks
name = "Flightpack Movement"
priority = 30
wait = 2
stat_tag = "FM"
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING
/datum/subsystem/processing/flightpacks/New()
/datum/controller/subsystem/processing/flightpacks/New()
NEW_SS_GLOBAL(SSflightpacks)
@@ -1,5 +1,5 @@
var/datum/subsystem/objects/SSobj
/datum/subsystem/objects
var/datum/controller/subsystem/objects/SSobj
/datum/controller/subsystem/objects
name = "Objects"
priority = 40
flags = SS_NO_INIT
@@ -7,12 +7,12 @@ var/datum/subsystem/objects/SSobj
var/list/processing = list()
var/list/currentrun = list()
/datum/subsystem/objects/New()
/datum/controller/subsystem/objects/New()
NEW_SS_GLOBAL(SSobj)
/datum/subsystem/objects/stat_entry()
/datum/controller/subsystem/objects/stat_entry()
..("P:[processing.len]")
/datum/subsystem/objects/fire(resumed = 0)
/datum/controller/subsystem/objects/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
@@ -28,5 +28,5 @@ var/datum/subsystem/objects/SSobj
if (MC_TICK_CHECK)
return
/datum/subsystem/objects/Recover()
/datum/controller/subsystem/objects/Recover()
processing = SSobj.processing
@@ -1,6 +1,6 @@
var/datum/subsystem/processing/overlays/SSoverlays
var/datum/controller/subsystem/processing/overlays/SSoverlays
/datum/subsystem/processing/overlays
/datum/controller/subsystem/processing/overlays
name = "Overlay"
flags = SS_TICKER|SS_FIRE_IN_LOBBY
wait = 1
@@ -13,33 +13,37 @@ var/datum/subsystem/processing/overlays/SSoverlays
var/list/overlay_icon_cache
var/initialized = FALSE
/datum/subsystem/processing/overlays/New()
/datum/controller/subsystem/processing/overlays/New()
NEW_SS_GLOBAL(SSoverlays)
LAZYINITLIST(overlay_icon_state_caches)
LAZYINITLIST(overlay_icon_cache)
/datum/subsystem/processing/overlays/Initialize()
/datum/controller/subsystem/processing/overlays/Initialize()
initialized = TRUE
for(var/I in processing)
var/atom/A = I
A.compile_overlays()
CHECK_TICK
processing.Cut()
Flush()
..()
/datum/subsystem/processing/overlays/Recover()
/datum/controller/subsystem/processing/overlays/Recover()
overlay_icon_state_caches = SSoverlays.overlay_icon_state_caches
overlay_icon_cache = SSoverlays.overlay_icon_cache
processing = SSoverlays.processing
/datum/subsystem/processing/overlays/fire()
/datum/controller/subsystem/processing/overlays/fire(resumed = FALSE, mc_check = TRUE)
while(processing.len)
var/atom/thing = processing[processing.len]
processing.len--
if(thing)
thing.compile_overlays(FALSE)
if(MC_TICK_CHECK)
break
if(mc_check)
if(MC_TICK_CHECK)
break
else
CHECK_TICK
/datum/controller/subsystem/processing/overlays/proc/Flush()
if(processing.len)
testing("Flushing [processing.len] overlays")
fire(mc_check = FALSE) //pair this thread up with the MC to get extra compile time
/atom/proc/compile_overlays()
if(LAZYLEN(priority_overlays) && LAZYLEN(our_overlays))
@@ -54,7 +58,7 @@ var/datum/subsystem/processing/overlays/SSoverlays
/proc/iconstate2appearance(icon, iconstate)
var/static/image/stringbro = new()
var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches
var/list/icon_states_cache = SSoverlays.overlay_icon_state_caches
var/list/cached_icon = icon_states_cache[icon]
if (cached_icon)
var/cached_appearance = cached_icon["[iconstate]"]
@@ -92,16 +96,17 @@ var/datum/subsystem/processing/overlays/SSoverlays
new_overlays[i] = icon2appearance(cached_overlay)
else //image probable
appearance_bro.appearance = cached_overlay
appearance_bro.dir = cached_overlay.dir
if(!ispath(cached_overlay))
appearance_bro.dir = cached_overlay.dir
new_overlays[i] = appearance_bro.appearance
return new_overlays
#define NOT_QUEUED_ALREADY (!(flags & OVERLAY_QUEUED))
#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.processing += src;
#define QUEUE_FOR_COMPILE flags |= OVERLAY_QUEUED; SSoverlays.processing += src;
/atom/proc/cut_overlays(priority = FALSE)
var/list/cached_overlays = our_overlays
var/list/cached_priority = priority_overlays
var/need_compile = FALSE
if(LAZYLEN(cached_overlays)) //don't queue empty lists, don't cut priority overlays
@@ -116,7 +121,6 @@ var/datum/subsystem/processing/overlays/SSoverlays
QUEUE_FOR_COMPILE
/atom/proc/cut_overlay(list/overlays, priority)
var/static/image/appearance_bro = new()
if(!overlays)
return
@@ -135,7 +139,6 @@ var/datum/subsystem/processing/overlays/SSoverlays
QUEUE_FOR_COMPILE
/atom/proc/add_overlay(list/overlays, priority = FALSE)
var/static/image/appearance_bro = new()
if(!overlays)
return
@@ -165,7 +168,7 @@ var/datum/subsystem/processing/overlays/SSoverlays
if(cut_old)
cut_overlays()
return
var/list/cached_other = other.our_overlays
if(cached_other)
if(cut_old)
@@ -188,4 +191,4 @@ var/datum/subsystem/processing/overlays/SSoverlays
overlays -= x
/image/proc/cut_overlays(x)
overlays.Cut()
overlays.Cut()
@@ -1,7 +1,7 @@
//Used to process objects. Fires once every second.
var/datum/subsystem/processing/SSprocessing
/datum/subsystem/processing
var/datum/controller/subsystem/processing/SSprocessing
/datum/controller/subsystem/processing
name = "Processing"
priority = 25
flags = SS_BACKGROUND|SS_POST_FIRE_TIMING|SS_NO_INIT
@@ -11,13 +11,13 @@ var/datum/subsystem/processing/SSprocessing
var/list/processing = list()
var/list/currentrun = list()
/datum/subsystem/processing/New()
/datum/controller/subsystem/processing/New()
NEW_SS_GLOBAL(SSprocessing)
/datum/subsystem/processing/stat_entry()
/datum/controller/subsystem/processing/stat_entry()
..("[stat_tag]:[processing.len]")
/datum/subsystem/processing/fire(resumed = 0)
/datum/controller/subsystem/processing/fire(resumed = 0)
if (!resumed)
currentrun = processing.Copy()
//cache for sanic speed (lists are references anyways)
+6 -6
View File
@@ -1,16 +1,16 @@
var/datum/subsystem/radio/SSradio
var/datum/controller/subsystem/radio/SSradio
/datum/subsystem/radio
/datum/controller/subsystem/radio
name = "Radio"
init_order = 18
flags = SS_NO_FIRE|SS_NO_INIT
var/list/datum/radio_frequency/frequencies = list()
/datum/subsystem/radio/New()
/datum/controller/subsystem/radio/New()
NEW_SS_GLOBAL(SSradio)
/datum/subsystem/radio/proc/add_object(obj/device, new_frequency as num, filter = null as text|null)
/datum/controller/subsystem/radio/proc/add_object(obj/device, new_frequency as num, filter = null as text|null)
var/f_text = num2text(new_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
@@ -22,7 +22,7 @@ var/datum/subsystem/radio/SSradio
frequency.add_listener(device, filter)
return frequency
/datum/subsystem/radio/proc/remove_object(obj/device, old_frequency)
/datum/controller/subsystem/radio/proc/remove_object(obj/device, old_frequency)
var/f_text = num2text(old_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
@@ -35,7 +35,7 @@ var/datum/subsystem/radio/SSradio
return 1
/datum/subsystem/radio/proc/return_frequency(new_frequency as num)
/datum/controller/subsystem/radio/proc/return_frequency(new_frequency as num)
var/f_text = num2text(new_frequency)
var/datum/radio_frequency/frequency = frequencies[f_text]
+3 -3
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/religion/SSreligion
var/datum/controller/subsystem/religion/SSreligion
/datum/subsystem/religion
/datum/controller/subsystem/religion
name = "Religion"
init_order = 19
flags = SS_NO_FIRE|SS_NO_INIT
@@ -13,5 +13,5 @@ var/datum/subsystem/religion/SSreligion
var/holy_weapon
/datum/subsystem/religion/New()
/datum/controller/subsystem/religion/New()
NEW_SS_GLOBAL(SSreligion)
@@ -1,28 +1,27 @@
var/datum/subsystem/server_maint/SSserver
var/datum/controller/subsystem/server_maint/SSserver
/datum/subsystem/server_maint
/datum/controller/subsystem/server_maint
name = "Server Tasks"
wait = 6000
flags = SS_NO_TICK_CHECK
/datum/subsystem/server_maint/New()
/datum/controller/subsystem/server_maint/New()
NEW_SS_GLOBAL(SSserver)
/datum/subsystem/server_maint/Initialize(timeofday)
/datum/controller/subsystem/server_maint/Initialize(timeofday)
if (config.hub)
world.visibility = 1
..()
/datum/subsystem/server_maint/fire()
/datum/controller/subsystem/server_maint/fire()
//handle kicking inactive players
if(config.kick_inactive > 0)
for(var/client/C in clients)
if(C.is_afk(INACTIVITY_KICK))
if(!istype(C.mob, /mob/dead))
log_access("AFK: [key_name(C)]")
C << "<span class='danger'>You have been inactive for more than 10 minutes and have been disconnected.</span>"
to_chat(C, "<span class='danger'>You have been inactive for more than 10 minutes and have been disconnected.</span>")
qdel(C)
if(config.sql_enabled)
sql_poll_players()
sql_poll_admins()
sql_poll_population()
+45 -42
View File
@@ -1,8 +1,8 @@
#define HIGHLIGHT_DYNAMIC_TRANSIT 1
var/datum/subsystem/shuttle/SSshuttle
var/datum/controller/subsystem/shuttle/SSshuttle
/datum/subsystem/shuttle
/datum/controller/subsystem/shuttle
name = "Shuttles"
wait = 10
init_order = 3
@@ -18,6 +18,7 @@ var/datum/subsystem/shuttle/SSshuttle
//emergency shuttle stuff
var/obj/docking_port/mobile/emergency/emergency
var/obj/docking_port/mobile/arrivals/arrivals
var/obj/docking_port/mobile/emergency/backup/backup_shuttle
var/emergencyCallTime = 6000 //time taken for emergency shuttle to reach the station when called (in deciseconds)
var/emergencyDockTime = 1800 //time taken for emergency shuttle to leave again once it has docked (in deciseconds)
@@ -46,10 +47,12 @@ var/datum/subsystem/shuttle/SSshuttle
var/lockdown = FALSE //disallow transit after nuke goes off
/datum/subsystem/shuttle/New()
/datum/controller/subsystem/shuttle/New()
NEW_SS_GLOBAL(SSshuttle)
/datum/subsystem/shuttle/Initialize(timeofday)
/datum/controller/subsystem/shuttle/Initialize(timeofday)
if(!emergency)
WARNING("No /obj/docking_port/mobile/arrivals placed on the map!")
if(!emergency)
WARNING("No /obj/docking_port/mobile/emergency placed on the map!")
if(!backup_shuttle)
@@ -65,13 +68,14 @@ var/datum/subsystem/shuttle/SSshuttle
continue
supply_packs[P.type] = P
initial_move()
setup_transit_zone()
initial_move()
#ifdef HIGHLIGHT_DYNAMIC_TRANSIT
color_space()
#endif
..()
/datum/subsystem/shuttle/proc/setup_transit_zone()
/datum/controller/subsystem/shuttle/proc/setup_transit_zone()
if(transit_markers.len == 0)
WARNING("No /obj/effect/landmark/transit placed on the map!")
return
@@ -85,7 +89,7 @@ var/datum/subsystem/shuttle/SSshuttle
T.flags |= UNUSED_TRANSIT_TURF
#ifdef HIGHLIGHT_DYNAMIC_TRANSIT
/datum/subsystem/shuttle/proc/color_space()
/datum/controller/subsystem/shuttle/proc/color_space()
if(transit_markers.len == 0)
WARNING("No /obj/effect/landmark/transit placed on the map!")
return
@@ -104,7 +108,7 @@ var/datum/subsystem/shuttle/SSshuttle
//world.log << "[transit_turfs.len] transit turfs registered"
/datum/subsystem/shuttle/fire()
/datum/controller/subsystem/shuttle/fire()
for(var/thing in mobile)
if(!thing)
mobile.Remove(thing)
@@ -148,19 +152,19 @@ var/datum/subsystem/shuttle/SSshuttle
if(MC_TICK_CHECK)
return
/datum/subsystem/shuttle/proc/getShuttle(id)
/datum/controller/subsystem/shuttle/proc/getShuttle(id)
for(var/obj/docking_port/mobile/M in mobile)
if(M.id == id)
return M
WARNING("couldn't find shuttle with id: [id]")
/datum/subsystem/shuttle/proc/getDock(id)
/datum/controller/subsystem/shuttle/proc/getDock(id)
for(var/obj/docking_port/stationary/S in stationary)
if(S.id == id)
return S
WARNING("couldn't find dock with id: [id]")
/datum/subsystem/shuttle/proc/requestEvac(mob/user, call_reason)
/datum/controller/subsystem/shuttle/proc/requestEvac(mob/user, call_reason)
if(!emergency)
WARNING("requestEvac(): There is no emergency shuttle, but the \
shuttle was called. Using the backup shuttle instead.")
@@ -176,33 +180,33 @@ var/datum/subsystem/shuttle/SSshuttle
emergency = backup_shuttle
if(world.time - round_start_time < config.shuttle_refuel_delay)
user << "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again."
to_chat(user, "The emergency shuttle is refueling. Please wait another [abs(round(((world.time - round_start_time) - config.shuttle_refuel_delay)/600))] minutes before trying again.")
return
switch(emergency.mode)
if(SHUTTLE_RECALL)
user << "The emergency shuttle may not be called while returning to Centcom."
to_chat(user, "The emergency shuttle may not be called while returning to Centcom.")
return
if(SHUTTLE_CALL)
user << "The emergency shuttle is already on its way."
to_chat(user, "The emergency shuttle is already on its way.")
return
if(SHUTTLE_DOCKED)
user << "The emergency shuttle is already here."
to_chat(user, "The emergency shuttle is already here.")
return
if(SHUTTLE_IGNITING)
user << "The emergency shuttle is firing its engines to leave."
to_chat(user, "The emergency shuttle is firing its engines to leave.")
return
if(SHUTTLE_ESCAPE)
user << "The emergency shuttle is moving away to a safe distance."
to_chat(user, "The emergency shuttle is moving away to a safe distance.")
return
if(SHUTTLE_STRANDED)
user << "The emergency shuttle has been disabled by Centcom."
to_chat(user, "The emergency shuttle has been disabled by Centcom.")
return
call_reason = trim(html_encode(call_reason))
if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH && seclevel2num(get_security_level()) > SEC_LEVEL_GREEN)
user << "You must provide a reason."
to_chat(user, "You must provide a reason.")
return
var/area/signal_origin = get_area(user)
@@ -221,20 +225,20 @@ var/datum/subsystem/shuttle/SSshuttle
// Called when an emergency shuttle mobile docking port is
// destroyed, which will only happen with admin intervention
/datum/subsystem/shuttle/proc/emergencyDeregister()
/datum/controller/subsystem/shuttle/proc/emergencyDeregister()
// When a new emergency shuttle is created, it will override the
// backup shuttle.
src.emergency = src.backup_shuttle
/datum/subsystem/shuttle/proc/cancelEvac(mob/user)
/datum/controller/subsystem/shuttle/proc/cancelEvac(mob/user)
if(canRecall())
emergency.cancel(get_area(user))
log_game("[key_name(user)] has recalled the shuttle.")
message_admins("[key_name_admin(user)] has recalled the shuttle.")
return 1
/datum/subsystem/shuttle/proc/canRecall()
if(emergency.mode != SHUTTLE_CALL)
/datum/controller/subsystem/shuttle/proc/canRecall()
if(!emergency || emergency.mode != SHUTTLE_CALL)
return
if(ticker.mode.name == "meteor")
return
@@ -251,7 +255,7 @@ var/datum/subsystem/shuttle/SSshuttle
return
return 1
/datum/subsystem/shuttle/proc/autoEvac()
/datum/controller/subsystem/shuttle/proc/autoEvac()
var/callShuttle = 1
for(var/thing in shuttle_caller_list)
@@ -275,15 +279,15 @@ var/datum/subsystem/shuttle/SSshuttle
log_game("There is no means of calling the shuttle anymore. Shuttle automatically called.")
message_admins("All the communications consoles were destroyed and all AIs are inactive. Shuttle called.")
/datum/subsystem/shuttle/proc/registerHostileEnvironment(datum/bad)
/datum/controller/subsystem/shuttle/proc/registerHostileEnvironment(datum/bad)
hostileEnvironments[bad] = TRUE
checkHostileEnvironment()
/datum/subsystem/shuttle/proc/clearHostileEnvironment(datum/bad)
/datum/controller/subsystem/shuttle/proc/clearHostileEnvironment(datum/bad)
hostileEnvironments -= bad
checkHostileEnvironment()
/datum/subsystem/shuttle/proc/checkHostileEnvironment()
/datum/controller/subsystem/shuttle/proc/checkHostileEnvironment()
for(var/datum/d in hostileEnvironments)
if(!istype(d) || QDELETED(d))
hostileEnvironments -= d
@@ -304,7 +308,7 @@ var/datum/subsystem/shuttle/SSshuttle
null, 'sound/AI/shuttledock.ogg', "Priority")
//try to move/request to dockHome if possible, otherwise dockAway. Mainly used for admin buttons
/datum/subsystem/shuttle/proc/toggleShuttle(shuttleId, dockHome, dockAway, timed)
/datum/controller/subsystem/shuttle/proc/toggleShuttle(shuttleId, dockHome, dockAway, timed)
var/obj/docking_port/mobile/M = getShuttle(shuttleId)
if(!M)
return 1
@@ -321,7 +325,7 @@ var/datum/subsystem/shuttle/SSshuttle
return 0 //dock successful
/datum/subsystem/shuttle/proc/moveShuttle(shuttleId, dockId, timed)
/datum/controller/subsystem/shuttle/proc/moveShuttle(shuttleId, dockId, timed)
var/obj/docking_port/mobile/M = getShuttle(shuttleId)
var/obj/docking_port/stationary/D = getDock(dockId)
@@ -335,7 +339,7 @@ var/datum/subsystem/shuttle/SSshuttle
return 2
return 0 //dock successful
/datum/subsystem/shuttle/proc/request_transit_dock(obj/docking_port/mobile/M)
/datum/controller/subsystem/shuttle/proc/request_transit_dock(obj/docking_port/mobile/M)
if(!istype(M))
throw EXCEPTION("[M] is not a mobile docking port")
@@ -345,7 +349,7 @@ var/datum/subsystem/shuttle/SSshuttle
if(!(M in transit_requesters))
transit_requesters += M
/datum/subsystem/shuttle/proc/generate_transit_dock(obj/docking_port/mobile/M)
/datum/controller/subsystem/shuttle/proc/generate_transit_dock(obj/docking_port/mobile/M)
// First, determine the size of the needed zone
// Because of shuttle rotation, the "width" of the shuttle is not
// always x.
@@ -368,7 +372,7 @@ var/datum/subsystem/shuttle/SSshuttle
transit_width += M.height
transit_height += M.width
/*
world << "The attempted transit dock will be [transit_width] width, and \
to_chat(world, "The attempted transit dock will be [transit_width] width, and \)
[transit_height] in height. The travel dir is [travel_dir]."
*/
@@ -398,17 +402,17 @@ var/datum/subsystem/shuttle/SSshuttle
continue base
if(!(T.flags & UNUSED_TRANSIT_TURF))
continue base
//world << "[COORD(topleft)] and [COORD(bottomright)]"
//to_chat(world, "[COORD(topleft)] and [COORD(bottomright)]")
break base
if((!proposed_zone) || (!proposed_zone.len))
return FALSE
var/turf/topleft = proposed_zone[1]
//world << "[COORD(topleft)] is TOPLEFT"
//to_chat(world, "[COORD(topleft)] is TOPLEFT")
// Then create a transit docking port in the middle
var/coords = M.return_coords(0, 0, dock_dir)
//world << json_encode(coords)
//to_chat(world, json_encode(coords))
/* 0------2
| |
| |
@@ -429,7 +433,7 @@ var/datum/subsystem/shuttle/SSshuttle
var/turf/low_point = locate(lowx, lowy, topleft.z)
new /obj/effect/landmark/stationary(low_point)
world << "Starting at the low point, we go [x2],[y2]"
to_chat(world, "Starting at the low point, we go [x2],[y2]")
*/
// Then invert the numbers
var/transit_x = topleft.x + SHUTTLE_TRANSIT_BORDER + abs(x2)
@@ -446,11 +450,11 @@ var/datum/subsystem/shuttle/SSshuttle
if(WEST)
transit_path = /turf/open/space/transit/west
//world << "Docking port at [transit_x], [transit_y], [topleft.z]"
//to_chat(world, "Docking port at [transit_x], [transit_y], [topleft.z]")
var/turf/midpoint = locate(transit_x, transit_y, topleft.z)
if(!midpoint)
return FALSE
//world << "Making transit dock at [COORD(midpoint)]"
//to_chat(world, "Making transit dock at [COORD(midpoint)]")
var/area/shuttle/transit/A = new()
A.parallax_movedir = travel_dir
var/obj/docking_port/stationary/transit/new_transit_dock = new(midpoint)
@@ -473,14 +477,14 @@ var/datum/subsystem/shuttle/SSshuttle
M.assigned_transit = new_transit_dock
return TRUE
/datum/subsystem/shuttle/proc/initial_move()
/datum/controller/subsystem/shuttle/proc/initial_move()
for(var/obj/docking_port/mobile/M in mobile)
if(!M.roundstart_move)
continue
M.dockRoundstart()
CHECK_TICK
/datum/subsystem/shuttle/Recover()
/datum/controller/subsystem/shuttle/Recover()
if (istype(SSshuttle.mobile))
mobile = SSshuttle.mobile
if (istype(SSshuttle.stationary))
@@ -504,5 +508,4 @@ var/datum/subsystem/shuttle/SSshuttle
centcom_message = SSshuttle.centcom_message
ordernum = SSshuttle.ordernum
points = SSshuttle.points
points = SSshuttle.points
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/spacedrift/SSspacedrift
var/datum/controller/subsystem/spacedrift/SSspacedrift
/datum/subsystem/spacedrift
/datum/controller/subsystem/spacedrift
name = "Space Drift"
priority = 30
wait = 5
@@ -9,15 +9,15 @@ var/datum/subsystem/spacedrift/SSspacedrift
var/list/currentrun = list()
var/list/processing = list()
/datum/subsystem/spacedrift/New()
/datum/controller/subsystem/spacedrift/New()
NEW_SS_GLOBAL(SSspacedrift)
/datum/subsystem/spacedrift/stat_entry()
/datum/controller/subsystem/spacedrift/stat_entry()
..("P:[processing.len]")
/datum/subsystem/spacedrift/fire(resumed = 0)
/datum/controller/subsystem/spacedrift/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+6 -6
View File
@@ -1,23 +1,23 @@
var/datum/subsystem/squeak/SSsqueak
var/datum/controller/subsystem/squeak/SSsqueak
// The Squeak
// because this is about placement of mice mobs, and nothing to do with
// mice - the computer peripheral
/datum/subsystem/squeak
/datum/controller/subsystem/squeak
name = "Squeak"
priority = 40
flags = SS_NO_FIRE
var/list/exposed_wires = list()
/datum/subsystem/squeak/New()
/datum/controller/subsystem/squeak/New()
NEW_SS_GLOBAL(SSsqueak)
/datum/subsystem/squeak/Initialize(timeofday)
/datum/controller/subsystem/squeak/Initialize(timeofday)
trigger_migration()
/datum/subsystem/squeak/proc/trigger_migration(num_mice=10)
/datum/controller/subsystem/squeak/proc/trigger_migration(num_mice=10)
find_exposed_wires()
var/mob/living/simple_animal/mouse/M
@@ -33,7 +33,7 @@ var/datum/subsystem/squeak/SSsqueak
num_mice -= 1
M = null
/datum/subsystem/squeak/proc/find_exposed_wires()
/datum/controller/subsystem/squeak/proc/find_exposed_wires()
exposed_wires.Cut()
var/list/all_turfs = block(locate(1,1,1), locate(world.maxx,world.maxy,1))
+4 -4
View File
@@ -1,16 +1,16 @@
var/datum/subsystem/stickyban/SSstickyban
var/datum/controller/subsystem/stickyban/SSstickyban
/datum/subsystem/stickyban
/datum/controller/subsystem/stickyban
name = "Sticky Ban"
init_order = -10
flags = SS_NO_FIRE
var/list/cache = list()
/datum/subsystem/stickyban/New()
/datum/controller/subsystem/stickyban/New()
NEW_SS_GLOBAL(SSstickyban)
/datum/subsystem/stickyban/Initialize(timeofday)
/datum/controller/subsystem/stickyban/Initialize(timeofday)
var/list/bannedkeys = world.GetConfig("ban")
//sanitize the sticky ban list
for (var/bannedkey in bannedkeys)
+5 -5
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/sun/SSsun
var/datum/controller/subsystem/sun/SSsun
/datum/subsystem/sun
/datum/controller/subsystem/sun
name = "Sun"
wait = 600
init_order = 2
@@ -11,7 +11,7 @@ var/datum/subsystem/sun/SSsun
var/rate
var/list/solars = list()
/datum/subsystem/sun/New()
/datum/controller/subsystem/sun/New()
NEW_SS_GLOBAL(SSsun)
angle = rand (0,360) // the station position to the sun is randomised at round start
@@ -19,10 +19,10 @@ var/datum/subsystem/sun/SSsun
if(prob(50)) // same chance to rotate clockwise than counter-clockwise
rate = -rate
/datum/subsystem/sun/stat_entry(msg)
/datum/controller/subsystem/sun/stat_entry(msg)
..("P:[solars.len]")
/datum/subsystem/sun/fire()
/datum/controller/subsystem/sun/fire()
angle = (360 + angle + rate * 6) % 360 // increase/decrease the angle to the sun, adjusted by the rate
// now calculate and cache the (dx,dy) increments for line drawing
+6 -7
View File
@@ -1,10 +1,9 @@
var/datum/subsystem/tgui/SStgui
var/datum/controller/subsystem/tgui/SStgui
/datum/subsystem/tgui
/datum/controller/subsystem/tgui
name = "tgui"
wait = 9
init_order = 16
display_order = 6
flags = SS_NO_INIT|SS_FIRE_IN_LOBBY
priority = 110
@@ -13,18 +12,18 @@ var/datum/subsystem/tgui/SStgui
var/list/processing_uis = list() // A list of processing UIs, ungrouped.
var/basehtml // The HTML base used for all UIs.
/datum/subsystem/tgui/New()
/datum/controller/subsystem/tgui/New()
basehtml = file2text('tgui/tgui.html') // Read the HTML from disk.
NEW_SS_GLOBAL(SStgui)
/datum/subsystem/tgui/Shutdown()
/datum/controller/subsystem/tgui/Shutdown()
close_all_uis()
/datum/subsystem/tgui/stat_entry()
/datum/controller/subsystem/tgui/stat_entry()
..("P:[processing_uis.len]")
/datum/subsystem/tgui/fire(resumed = 0)
/datum/controller/subsystem/tgui/fire(resumed = 0)
if (!resumed)
src.currentrun = processing_uis.Copy()
//cache for sanic speed (lists are references anyways)
+5 -5
View File
@@ -1,8 +1,8 @@
#define MAX_THROWING_DIST 512 // 2 z-levels on default width
#define MAX_TICKS_TO_MAKE_UP 3 //how many missed ticks will we attempt to make up for this run.
var/datum/subsystem/throwing/SSthrowing
var/datum/controller/subsystem/throwing/SSthrowing
/datum/subsystem/throwing
/datum/controller/subsystem/throwing
name = "Throwing"
priority = 25
wait = 1
@@ -11,16 +11,16 @@ var/datum/subsystem/throwing/SSthrowing
var/list/currentrun
var/list/processing
/datum/subsystem/throwing/New()
/datum/controller/subsystem/throwing/New()
NEW_SS_GLOBAL(SSthrowing)
processing = list()
/datum/subsystem/throwing/stat_entry()
/datum/controller/subsystem/throwing/stat_entry()
..("P:[processing.len]")
/datum/subsystem/throwing/fire(resumed = 0)
/datum/controller/subsystem/throwing/fire(resumed = 0)
if (!resumed)
src.currentrun = processing.Copy()
+124 -98
View File
@@ -2,9 +2,9 @@
var/round_start_time = 0
var/datum/subsystem/ticker/ticker
var/datum/controller/subsystem/ticker/ticker
/datum/subsystem/ticker
/datum/controller/subsystem/ticker
name = "Ticker"
init_order = 13
@@ -56,19 +56,17 @@ var/datum/subsystem/ticker/ticker
var/news_report
var/modevoted = 0 //Have we sent a vote for the gamemode?
var/late_join_disabled
/datum/subsystem/ticker/New()
var/modevoted = FALSE //Have we sent a vote for the gamemode?
/datum/controller/subsystem/ticker/New()
NEW_SS_GLOBAL(ticker)
if(SSevent.holidays && SSevent.holidays[APRIL_FOOLS])
login_music = 'sound/ambience/clown.ogg'
else
var/list/music = file2list(ROUND_START_MUSIC_LIST, "\n")
login_music = pick(music)
/datum/subsystem/ticker/Initialize(timeofday)
/datum/controller/subsystem/ticker/Initialize(timeofday)
var/list/music = file2list(ROUND_START_MUSIC_LIST, "\n")
login_music = pick(music)
if(!syndicate_code_phrase)
syndicate_code_phrase = generate_code_phrase()
if(!syndicate_code_response)
@@ -76,14 +74,14 @@ var/datum/subsystem/ticker/ticker
..()
start_at = world.time + (config.lobby_countdown * 10)
/datum/subsystem/ticker/fire()
/datum/controller/subsystem/ticker/fire()
switch(current_state)
if(GAME_STATE_STARTUP)
if(Master.initializations_finished_with_no_players_logged_in)
start_at = world.time + (config.lobby_countdown * 10)
for(var/client/C in clients)
window_flash(C, ignorepref = TRUE) //let them know lobby has opened up.
world << "<span class='boldnotice'>Welcome to [station_name()]!</span>"
to_chat(world, "<span class='boldnotice'>Welcome to [station_name()]!</span>")
current_state = GAME_STATE_PREGAME
if(!modevoted)
send_gamemode_vote()
@@ -95,7 +93,7 @@ var/datum/subsystem/ticker/ticker
timeLeft = max(0,start_at - world.time)
totalPlayers = 0
totalPlayersReady = 0
for(var/mob/new_player/player in player_list)
for(var/mob/dead/new_player/player in player_list)
++totalPlayers
if(player.ready)
++totalPlayersReady
@@ -133,7 +131,9 @@ var/datum/subsystem/ticker/ticker
toggle_ooc(1) // Turn it on
declare_completion(force_ending)
/datum/subsystem/ticker/proc/setup()
/datum/controller/subsystem/ticker/proc/setup()
to_chat(world, "<span class='boldannounce'>Starting game...</span>")
var/init_start = world.timeofday
//Create and announce mode
var/list/datum/game_mode/runnable_modes
if(master_mode == "random" || master_mode == "secret")
@@ -150,71 +150,83 @@ var/datum/subsystem/ticker/ticker
if(!mode)
if(!runnable_modes.len)
world << "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby."
to_chat(world, "<B>Unable to choose playable game mode.</B> Reverting to pre-game lobby.")
return 0
mode = pickweight(runnable_modes)
else
mode = config.pick_mode(master_mode)
if(!mode.can_start())
world << "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby."
to_chat(world, "<B>Unable to start [mode.name].</B> Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby.")
qdel(mode)
mode = null
SSjob.ResetOccupations()
return 0
CHECK_TICK
//Configure mode and assign player to special mode stuff
var/can_continue = 0
can_continue = src.mode.pre_setup() //Choose antagonists
CHECK_TICK
SSjob.DivideOccupations() //Distribute jobs
CHECK_TICK
if(!Debug2)
if(!can_continue)
qdel(mode)
mode = null
world << "<B>Error setting up [master_mode].</B> Reverting to pre-game lobby."
to_chat(world, "<B>Error setting up [master_mode].</B> Reverting to pre-game lobby.")
SSjob.ResetOccupations()
return 0
else
message_admins("<span class='notice'>DEBUG: Bypassing prestart checks...</span>")
CHECK_TICK
if(hide_mode)
var/list/modes = new
for (var/datum/game_mode/M in runnable_modes)
modes += M.name
modes = sortList(modes)
world << "<b>The gamemode is: secret!\n\
Possibilities:</B> [english_list(modes)]"
to_chat(world, "<b>The gamemode is: secret!\nPossibilities:</B> [english_list(modes)]")
else
mode.announce()
current_state = GAME_STATE_PLAYING
if(!config.ooc_during_round)
toggle_ooc(0) // Turn it off
round_start_time = world.time
CHECK_TICK
start_landmarks_list = shuffle(start_landmarks_list) //Shuffle the order of spawn points so they dont always predictably spawn bottom-up and right-to-left
create_characters() //Create player characters and transfer them
create_characters() //Create player characters
collect_minds()
equip_characters()
SSoverlays.Flush() //Flush the majority of the shit
data_core.manifest()
Master.RoundStart()
transfer_characters() //transfer keys to the new mobs
world << "<FONT color='blue'><B>Welcome to [station_name()], enjoy your stay!</B></FONT>"
Master.RoundStart() //let the party begin...
log_world("Game start took [(world.timeofday - init_start)/10]s")
round_start_time = world.time
to_chat(world, "<FONT color='blue'><B>Welcome to [station_name()], enjoy your stay!</B></FONT>")
world << sound('sound/AI/welcome.ogg')
current_state = GAME_STATE_PLAYING
if(SSevent.holidays)
world << "<font color='blue'>and...</font>"
to_chat(world, "<font color='blue'>and...</font>")
for(var/holidayname in SSevent.holidays)
var/datum/holiday/holiday = SSevent.holidays[holidayname]
world << "<h4>[holiday.greet()]</h4>"
to_chat(world, "<h4>[holiday.greet()]</h4>")
PostSetup()
return 1
/datum/subsystem/ticker/proc/PostSetup()
/datum/controller/subsystem/ticker/proc/PostSetup()
set waitfor = 0
mode.post_setup()
//Cleanup some stuff
@@ -227,7 +239,7 @@ var/datum/subsystem/ticker/ticker
var/list/allmins = adm["present"]
send2irc("Server", "Round of [hide_mode ? "secret":"[mode.name]"] has started[allmins.len ? ".":" with no active admins online!"]")
/datum/subsystem/ticker/proc/station_explosion_detonation(atom/bomb)
/datum/controller/subsystem/ticker/proc/station_explosion_detonation(atom/bomb)
if(bomb) //BOOM
var/turf/epi = bomb.loc
qdel(bomb)
@@ -235,7 +247,7 @@ var/datum/subsystem/ticker/ticker
explosion(epi, 0, 256, 512, 0, TRUE, TRUE, 0, TRUE)
//Plus it provides an easy way to make cinematics for other events. Just use this as a template
/datum/subsystem/ticker/proc/station_explosion_cinematic(station_missed=0, override = null, atom/bomb = null)
/datum/controller/subsystem/ticker/proc/station_explosion_cinematic(station_missed=0, override = null, atom/bomb = null)
if( cinematic )
return //already a cinematic in progress!
@@ -344,12 +356,12 @@ var/datum/subsystem/ticker/ticker
if(mode)
mode.explosion_in_progress = 0
world << "<B>The station was destoyed by the nuclear blast!</B>"
to_chat(world, "<B>The station was destoyed by the nuclear blast!</B>")
mode.station_was_nuked = (station_missed<2) //station_missed==1 is a draw. the station becomes irradiated and needs to be evacuated.
addtimer(CALLBACK(src, .proc/finish_cinematic, bombloc, actually_blew_up), 300)
/datum/subsystem/ticker/proc/finish_cinematic(killz, actually_blew_up)
/datum/controller/subsystem/ticker/proc/finish_cinematic(killz, actually_blew_up)
if(cinematic)
qdel(cinematic) //end the cinematic
cinematic = null
@@ -358,49 +370,65 @@ var/datum/subsystem/ticker/ticker
if(actually_blew_up && !isnull(killz) && M.stat != DEAD && M.z == killz)
M.gib()
/datum/subsystem/ticker/proc/create_characters()
for(var/mob/new_player/player in player_list)
/datum/controller/subsystem/ticker/proc/create_characters()
for(var/mob/dead/new_player/player in player_list)
if(player.ready && player.mind)
joined_player_list += player.ckey
if(player.mind.assigned_role=="AI")
player.close_spawn_windows()
player.AIize()
else
player.create_character()
qdel(player)
player.create_character(FALSE)
else
player.new_player_panel()
CHECK_TICK
/datum/controller/subsystem/ticker/proc/collect_minds()
for(var/mob/dead/new_player/P in player_list)
if(P.new_character && P.new_character.mind)
ticker.minds += P.new_character.mind
CHECK_TICK
/datum/subsystem/ticker/proc/collect_minds()
for(var/mob/living/player in player_list)
if(player.mind)
ticker.minds += player.mind
/datum/subsystem/ticker/proc/equip_characters()
/datum/controller/subsystem/ticker/proc/equip_characters()
var/captainless=1
for(var/mob/living/carbon/human/player in player_list)
if(player && player.mind && player.mind.assigned_role)
for(var/mob/dead/new_player/N in player_list)
var/mob/living/carbon/human/player = N.new_character
if(istype(player) && player.mind && player.mind.assigned_role)
if(player.mind.assigned_role == "Captain")
captainless=0
if(player.mind.assigned_role != player.mind.special_role)
SSjob.EquipRank(player, player.mind.assigned_role, 0)
SSjob.EquipRank(N, player.mind.assigned_role, 0)
CHECK_TICK
if(captainless)
for(var/mob/M in player_list)
if(!isnewplayer(M))
M << "Captainship not forced on anyone."
for(var/mob/dead/new_player/N in player_list)
if(N.new_character)
to_chat(N, "Captainship not forced on anyone.")
CHECK_TICK
/datum/controller/subsystem/ticker/proc/transfer_characters()
var/list/livings = list()
for(var/mob/dead/new_player/player in player_list)
var/mob/living = player.transfer_character()
if(living)
qdel(player)
living.notransform = TRUE
if(living.client)
var/obj/screen/splash/S = new(living.client, TRUE)
S.Fade(TRUE)
livings += living
if(livings.len)
addtimer(CALLBACK(src, .proc/release_characters, livings), 30, TIMER_CLIENT_TIME)
/datum/controller/subsystem/ticker/proc/release_characters(list/livings)
for(var/I in livings)
var/mob/living/L = I
L.notransform = FALSE
/datum/subsystem/ticker/proc/declare_completion()
/datum/controller/subsystem/ticker/proc/declare_completion()
set waitfor = FALSE
var/station_evacuated = EMERGENCY_ESCAPED_OR_ENDGAMED
var/num_survivors = 0
var/num_escapees = 0
var/num_shuttle_escapees = 0
world << "<BR><BR><BR><FONT size=3><B>The round has ended.</B></FONT>"
to_chat(world, "<BR><BR><BR><FONT size=3><B>The round has ended.</B></FONT>")
//Player status report
for(var/mob/Player in mob_list)
@@ -412,16 +440,16 @@ var/datum/subsystem/ticker/ticker
if(SSshuttle && SSshuttle.emergency)
shuttle_area = SSshuttle.emergency.areaInstance
if(!Player.onCentcom() && !Player.onSyndieBase())
Player << "<font color='blue'><b>You managed to survive, but were marooned on [station_name()]...</b></FONT>"
to_chat(Player, "<font color='blue'><b>You managed to survive, but were marooned on [station_name()]...</b></FONT>")
else
num_escapees++
Player << "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>"
to_chat(Player, "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>")
if(get_area(Player) == shuttle_area)
num_shuttle_escapees++
else
Player << "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>"
to_chat(Player, "<font color='green'><b>You managed to survive the events on [station_name()] as [Player.real_name].</b></FONT>")
else
Player << "<font color='red'><b>You did not survive the events on [station_name()]...</b></FONT>"
to_chat(Player, "<font color='red'><b>You did not survive the events on [station_name()]...</b></FONT>")
CHECK_TICK
@@ -430,50 +458,50 @@ var/datum/subsystem/ticker/ticker
end_state.count()
var/station_integrity = min(PERCENT(start_state.score(end_state)), 100)
world << "<BR>[TAB]Shift Duration: <B>[round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B>"
world << "<BR>[TAB]Station Integrity: <B>[mode.station_was_nuked ? "<font color='red'>Destroyed</font>" : "[station_integrity]%"]</B>"
to_chat(world, "<BR>[TAB]Shift Duration: <B>[round(world.time / 36000)]:[add_zero("[world.time / 600 % 60]", 2)]:[world.time / 100 % 6][world.time / 100 % 10]</B>")
to_chat(world, "<BR>[TAB]Station Integrity: <B>[mode.station_was_nuked ? "<font color='red'>Destroyed</font>" : "[station_integrity]%"]</B>")
if(mode.station_was_nuked)
ticker.news_report = STATION_DESTROYED_NUKE
var/total_players = joined_player_list.len
if(joined_player_list.len)
world << "<BR>[TAB]Total Population: <B>[total_players]</B>"
to_chat(world, "<BR>[TAB]Total Population: <B>[total_players]</B>")
if(station_evacuated)
world << "<BR>[TAB]Evacuation Rate: <B>[num_escapees] ([PERCENT(num_escapees/total_players)]%)</B>"
world << "<BR>[TAB](on emergency shuttle): <B>[num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)</B>"
to_chat(world, "<BR>[TAB]Evacuation Rate: <B>[num_escapees] ([PERCENT(num_escapees/total_players)]%)</B>")
to_chat(world, "<BR>[TAB](on emergency shuttle): <B>[num_shuttle_escapees] ([PERCENT(num_shuttle_escapees/total_players)]%)</B>")
news_report = STATION_EVACUATED
if(SSshuttle.emergency.is_hijacked())
news_report = SHUTTLE_HIJACK
world << "<BR>[TAB]Survival Rate: <B>[num_survivors] ([PERCENT(num_survivors/total_players)]%)</B>"
world << "<BR>"
to_chat(world, "<BR>[TAB]Survival Rate: <B>[num_survivors] ([PERCENT(num_survivors/total_players)]%)</B>")
to_chat(world, "<BR>")
CHECK_TICK
//Silicon laws report
for (var/mob/living/silicon/ai/aiPlayer in mob_list)
if (aiPlayer.stat != 2 && aiPlayer.mind)
world << "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws at the end of the round were:</b>"
to_chat(world, "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws at the end of the round were:</b>")
aiPlayer.show_laws(1)
else if (aiPlayer.mind) //if the dead ai has a mind, use its key instead
world << "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws when it was deactivated were:</b>"
to_chat(world, "<b>[aiPlayer.name] (Played by: [aiPlayer.mind.key])'s laws when it was deactivated were:</b>")
aiPlayer.show_laws(1)
world << "<b>Total law changes: [aiPlayer.law_change_counter]</b>"
to_chat(world, "<b>Total law changes: [aiPlayer.law_change_counter]</b>")
if (aiPlayer.connected_robots.len)
var/robolist = "<b>[aiPlayer.real_name]'s minions were:</b> "
for(var/mob/living/silicon/robot/robo in aiPlayer.connected_robots)
if(robo.mind)
robolist += "[robo.name][robo.stat?" (Deactivated) (Played by: [robo.mind.key]), ":" (Played by: [robo.mind.key]), "]"
world << "[robolist]"
to_chat(world, "[robolist]")
CHECK_TICK
for (var/mob/living/silicon/robot/robo in mob_list)
if (!robo.connected_ai && robo.mind)
if (robo.stat != 2)
world << "<b>[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:</b>"
to_chat(world, "<b>[robo.name] (Played by: [robo.mind.key]) survived as an AI-less borg! Its laws were:</b>")
else
world << "<b>[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:</b>"
to_chat(world, "<b>[robo.name] (Played by: [robo.mind.key]) was unable to survive the rigors of being a cyborg without an AI. Its laws were:</b>")
if(robo) //How the hell do we lose robo between here and the world messages directly above this?
robo.laws.show_laws(world)
@@ -491,7 +519,7 @@ var/datum/subsystem/ticker/ticker
CHECK_TICK
if(cross_allowed)
if(config.cross_allowed)
send_news_report()
CHECK_TICK
@@ -530,7 +558,7 @@ var/datum/subsystem/ticker/ticker
else
borertext += "failed"
borertext += ")"
world << borertext
to_chat(world, borertext)
var/total_borers = 0
for(var/mob/living/simple_animal/borer/B in borers)
@@ -545,12 +573,12 @@ var/datum/subsystem/ticker/ticker
total_borer_hosts++
if(total_borer_hosts_needed <= total_borer_hosts)
borerwin = TRUE
world << "<b>There were [total_borers] borers alive at round end!</b>"
world << "<b>A total of [total_borer_hosts] borers with hosts escaped on the shuttle alive. The borers needed [total_borer_hosts_needed] hosts to escape.</b>"
to_chat(world, "<b>There were [total_borers] borers alive at round end!</b>")
to_chat(world, "<b>A total of [total_borer_hosts] borers with hosts escaped on the shuttle alive. The borers needed [total_borer_hosts_needed] hosts to escape.</b>")
if(borerwin)
world << "<b><font color='green'>The borers were successful!</font></b>"
to_chat(world, "<b><font color='green'>The borers were successful!</font></b>")
else
world << "<b><font color='red'>The borers have failed!</font></b>"
to_chat(world, "<b><font color='red'>The borers have failed!</font></b>")
CHECK_TICK
@@ -583,7 +611,7 @@ var/datum/subsystem/ticker/ticker
else
world.Reboot("Round ended.", "end_proper", "proper completion")
/datum/subsystem/ticker/proc/send_tip_of_the_round()
/datum/controller/subsystem/ticker/proc/send_tip_of_the_round()
var/m
if(selected_tip)
m = selected_tip
@@ -596,35 +624,34 @@ var/datum/subsystem/ticker/ticker
m = pick(memetips)
if(m)
world << "<font color='purple'><b>Tip of the round: \
</b>[html_encode(m)]</font>"
to_chat(world, "<font color='purple'><b>Tip of the round: </b>[html_encode(m)]</font>")
/datum/subsystem/ticker/proc/check_queue()
/datum/controller/subsystem/ticker/proc/check_queue()
if(!queued_players.len || !config.hard_popcap)
return
queue_delay++
var/mob/new_player/next_in_line = queued_players[1]
var/mob/dead/new_player/next_in_line = queued_players[1]
switch(queue_delay)
if(5) //every 5 ticks check if there is a slot available
if(living_player_count() < config.hard_popcap)
if(next_in_line && next_in_line.client)
next_in_line << "<span class='userdanger'>A slot has opened! You have approximately 20 seconds to join. <a href='?src=\ref[next_in_line];late_join=override'>\>\>Join Game\<\<</a></span>"
to_chat(next_in_line, "<span class='userdanger'>A slot has opened! You have approximately 20 seconds to join. <a href='?src=\ref[next_in_line];late_join=override'>\>\>Join Game\<\<</a></span>")
next_in_line << sound('sound/misc/notice1.ogg')
next_in_line.LateChoices()
return
queued_players -= next_in_line //Client disconnected, remove he
queue_delay = 0 //No vacancy: restart timer
if(25 to INFINITY) //No response from the next in line when a vacancy exists, remove he
next_in_line << "<span class='danger'>No response recieved. You have been removed from the line.</span>"
to_chat(next_in_line, "<span class='danger'>No response recieved. You have been removed from the line.</span>")
queued_players -= next_in_line
queue_delay = 0
/datum/subsystem/ticker/proc/check_maprotate()
if (!config.maprotation || !SERVERTOOLS)
/datum/controller/subsystem/ticker/proc/check_maprotate()
if (!config.maprotation)
return
if (SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall())
if (SSshuttle.emergency && SSshuttle.emergency.mode != SHUTTLE_ESCAPE || SSshuttle.canRecall())
return
if (maprotatechecked)
return
@@ -634,9 +661,9 @@ var/datum/subsystem/ticker/ticker
//map rotate chance defaults to 75% of the length of the round (in minutes)
if (!prob((world.time/600)*config.maprotatechancedelta))
return
INVOKE_ASYNC(GLOBAL_PROC, /.proc/maprotate)
INVOKE_ASYNC(SSmapping, /datum/controller/subsystem/mapping/.proc/maprotate)
/datum/subsystem/ticker/proc/send_gamemode_vote(var/)
/datum/controller/subsystem/ticker/proc/send_gamemode_vote(var/)
SSvote.initiate_vote("roundtype","server")
/world/proc/has_round_started()
@@ -644,7 +671,7 @@ var/datum/subsystem/ticker/ticker
return TRUE
return FALSE
/datum/subsystem/ticker/Recover()
/datum/controller/subsystem/ticker/Recover()
current_state = ticker.current_state
force_ending = ticker.force_ending
hide_mode = ticker.hide_mode
@@ -676,10 +703,9 @@ var/datum/subsystem/ticker/ticker
queued_players = ticker.queued_players
cinematic = ticker.cinematic
maprotatechecked = ticker.maprotatechecked
modevoted = ticker.modevoted
/datum/subsystem/ticker/proc/send_news_report()
/datum/controller/subsystem/ticker/proc/send_news_report()
var/news_message
var/news_source = "Nanotrasen News Network"
switch(news_report)
@@ -706,19 +732,19 @@ var/datum/subsystem/ticker/ticker
if(CULT_SUMMON)
news_message = "Company officials would like to clarify that [station_name()] was scheduled to be decommissioned following meteor damage earlier this year. Earlier reports of an unknowable eldritch horror were made in error."
if(NUKE_MISS)
news_message = "The Syndicate have bungled a terrorist attack [station_name()], detonating a nuclear weapon in empty space near by."
news_message = "The Syndicate have bungled a terrorist attack [station_name()], detonating a nuclear weapon in empty space nearby."
if(OPERATIVES_KILLED)
news_message = "Repairs to [station_name()] are underway after an elite Syndicate death squad was wiped out by the crew."
if(OPERATIVE_SKIRMISH)
news_message = "A skirmish between security forces and Syndicate agents aboard [station_name()] ended with both sides bloodied but intact."
if(REVS_WIN)
news_message = "Company officials have reassured investors that despite a union led revolt aboard [station_name()] that there will be no wage increases for workers."
news_message = "Company officials have reassured investors that despite a union led revolt aboard [station_name()] there will be no wage increases for workers."
if(REVS_LOSE)
news_message = "[station_name()] quickly put down a misguided attempt at mutiny. Remember, unionizing is illegal!"
if(WIZARD_KILLED)
news_message = "Tensions have flared with the Wizard's Federation following the death of one of their members aboard [station_name()]."
news_message = "Tensions have flared with the Space Wizard Federation following the death of one of their members aboard [station_name()]."
if(STATION_NUKED)
news_message = "[station_name()] activated its self destruct device for unknown reasons. Attempts to clone the Captain so he can be arrested and executed are under way."
news_message = "[station_name()] activated its self destruct device for unknown reasons. Attempts to clone the Captain so he can be arrested and executed are underway."
if(CLOCK_SUMMON)
news_message = "The garbled messages about hailing a mouse and strange energy readings from [station_name()] have been discovered to be an ill-advised, if thorough, prank by a clown."
if(CLOCK_SILICONS)
@@ -731,12 +757,12 @@ var/datum/subsystem/ticker/ticker
if(news_message)
send2otherserver(news_source, news_message,"News_Report")
/datum/subsystem/ticker/proc/GetTimeLeft()
/datum/controller/subsystem/ticker/proc/GetTimeLeft()
if(isnull(ticker.timeLeft))
return max(0, start_at - world.time)
return timeLeft
/datum/subsystem/ticker/proc/SetTimeLeft(newtime)
/datum/controller/subsystem/ticker/proc/SetTimeLeft(newtime)
if(newtime >= 0 && isnull(timeLeft)) //remember, negative means delayed
start_at = world.time + newtime
else
+4 -4
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/time_track/SStime_track
var/datum/controller/subsystem/time_track/SStime_track
/datum/subsystem/time_track
/datum/controller/subsystem/time_track
name = "Time Tracking"
wait = 600
flags = SS_NO_INIT|SS_FIRE_IN_LOBBY
@@ -17,10 +17,10 @@ var/datum/subsystem/time_track/SStime_track
var/last_tick_byond_time = 0
var/last_tick_tickcount = 0
/datum/subsystem/time_track/New()
/datum/controller/subsystem/time_track/New()
NEW_SS_GLOBAL(SStime_track)
/datum/subsystem/time_track/fire()
/datum/controller/subsystem/time_track/fire()
var/current_realtime = REALTIMEOFDAY
var/current_byondtime = world.time
+7 -8
View File
@@ -1,12 +1,11 @@
#define BUCKET_LEN (world.fps*1*60) //how many ticks should we keep in the bucket. (1 minutes worth)
#define BUCKET_POS(timer) (round((timer.timeToRun - SStimer.head_offset) / world.tick_lag) + 1)
var/datum/subsystem/timer/SStimer
var/datum/controller/subsystem/timer/SStimer
/datum/subsystem/timer
/datum/controller/subsystem/timer
name = "Timer"
wait = 1 //SS_TICKER subsystem, so wait is in ticks
init_order = 1
display_order = 3
flags = SS_FIRE_IN_LOBBY|SS_TICKER|SS_NO_INIT
@@ -25,7 +24,7 @@ var/datum/subsystem/timer/SStimer
var/list/clienttime_timers //special snowflake timers that run on fancy pansy "client time"
/datum/subsystem/timer/New()
/datum/controller/subsystem/timer/New()
processing = list()
hashes = list()
bucket_list = list()
@@ -36,10 +35,10 @@ var/datum/subsystem/timer/SStimer
NEW_SS_GLOBAL(SStimer)
/datum/subsystem/timer/stat_entry(msg)
/datum/controller/subsystem/timer/stat_entry(msg)
..("B:[bucket_count] P:[length(processing)] H:[length(hashes)] C:[length(clienttime_timers)]")
/datum/subsystem/timer/fire(resumed = FALSE)
/datum/controller/subsystem/timer/fire(resumed = FALSE)
while(length(clienttime_timers))
var/datum/timedevent/ctime_timer = clienttime_timers[clienttime_timers.len]
if (ctime_timer.timeToRun <= REALTIMEOFDAY)
@@ -107,7 +106,7 @@ var/datum/subsystem/timer/SStimer
spent.len = 0
/datum/subsystem/timer/proc/shift_buckets()
/datum/controller/subsystem/timer/proc/shift_buckets()
var/list/bucket_list = src.bucket_list
var/list/alltimers = list()
//collect the timers currently in the bucket
@@ -172,7 +171,7 @@ var/datum/subsystem/timer/SStimer
processing = (alltimers - timers_to_remove)
/datum/subsystem/timer/Recover()
/datum/controller/subsystem/timer/Recover()
processing |= SStimer.processing
hashes |= SStimer.hashes
timer_id_dict |= SStimer.timer_id_dict
@@ -0,0 +1,39 @@
var/datum/controller/subsystem/title/SStitle
/datum/controller/subsystem/title
name = "Title Screen"
init_order = 15
flags = SS_NO_FIRE
var/turf/closed/indestructible/splashscreen/title_screen
/datum/controller/subsystem/title/New()
NEW_SS_GLOBAL(SStitle)
/datum/controller/subsystem/title/Initialize()
var/list/provisional_title_screens = flist("config/title_screens/images/")
var/list/title_screens = list()
var/use_rare_screens = FALSE
if(title_screen)
if(prob(1))
use_rare_screens = TRUE
for(var/S in provisional_title_screens)
var/list/L = splittext(S,"+")
if((L.len == 1 && L[1] != "blank.png")|| (L.len > 1 && ((use_rare_screens && lowertext(L[1]) == "rare") || (lowertext(L[1]) == lowertext(SSmapping.config.map_name)))))
title_screens += S
if(!isemptylist(title_screens))
if(length(title_screens) > 1)
for(var/S in title_screens)
var/list/L = splittext(S,".")
if(L.len != 2 || L[1] != "default")
continue
title_screens -= S
break
var/path_string = "config/title_screens/images/[pick(title_screens)]"
var/icon/screen_to_use = new(path_string)
title_screen.icon = screen_to_use
..()
+20 -21
View File
@@ -1,6 +1,6 @@
var/datum/subsystem/vote/SSvote
var/datum/controller/subsystem/vote/SSvote
/datum/subsystem/vote
/datum/controller/subsystem/vote
name = "Vote"
wait = 10
@@ -16,10 +16,10 @@ var/datum/subsystem/vote/SSvote
var/list/voting = list()
var/list/generated_actions = list()
/datum/subsystem/vote/New()
/datum/controller/subsystem/vote/New()
NEW_SS_GLOBAL(SSvote)
/datum/subsystem/vote/fire() //called by master_controller
/datum/controller/subsystem/vote/fire() //called by master_controller
if(mode)
time_remaining = round((started_time + config.vote_period - world.time)/10)
@@ -37,7 +37,7 @@ var/datum/subsystem/vote/SSvote
client_popup.open(0)
/datum/subsystem/vote/proc/reset()
/datum/controller/subsystem/vote/proc/reset()
initiator = null
time_remaining = 0
mode = null
@@ -47,7 +47,7 @@ var/datum/subsystem/vote/SSvote
voting.Cut()
remove_action_buttons()
/datum/subsystem/vote/proc/get_result()
/datum/controller/subsystem/vote/proc/get_result()
//get the highest number of votes
var/greatest_votes = 0
var/total_votes = 0
@@ -82,7 +82,7 @@ var/datum/subsystem/vote/SSvote
. += option
return .
/datum/subsystem/vote/proc/announce_result()
/datum/controller/subsystem/vote/proc/announce_result()
var/list/winners = get_result()
var/text
if(winners.len > 0)
@@ -108,10 +108,10 @@ var/datum/subsystem/vote/SSvote
text += "<b>Vote Result: Inconclusive - No Votes!</b>"
log_vote(text)
remove_action_buttons()
world << "\n<font color='purple'>[text]</font>"
to_chat(world, "\n<font color='purple'>[text]</font>")
return .
/datum/subsystem/vote/proc/result()
/datum/controller/subsystem/vote/proc/result()
. = announce_result()
var/restart = 0
if(.)
@@ -133,7 +133,7 @@ var/datum/subsystem/vote/SSvote
else if(master_mode != .)
world.save_mode(.)
master_mode = .
world << "<span class='adminnotice'><b>The mode is now: [master_mode]</b></span>"
to_chat(world,"<span class='adminnotice'><b>The mode is now: [master_mode]</b></span>")
if(restart)
var/active_admins = 0
@@ -144,12 +144,12 @@ var/datum/subsystem/vote/SSvote
if(!active_admins)
world.Reboot("Restart vote successful.", "end_error", "restart vote")
else
world << "<span style='boldannounce'>Notice:Restart vote will not restart the server automatically because there are active admins on.</span>"
to_chat(world, "<span style='boldannounce'>Notice:Restart vote will not restart the server automatically because there are active admins on.</span>")
message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.")
return .
/datum/subsystem/vote/proc/submit_vote(vote)
/datum/controller/subsystem/vote/proc/submit_vote(vote)
if(mode)
if(config.vote_no_dead && usr.stat == DEAD && !usr.client.holder)
return 0
@@ -160,12 +160,12 @@ var/datum/subsystem/vote/SSvote
return vote
return 0
/datum/subsystem/vote/proc/initiate_vote(vote_type, initiator_key)
/datum/controller/subsystem/vote/proc/initiate_vote(vote_type, initiator_key)
if(!mode)
if(started_time)
var/next_allowed_time = (started_time + config.vote_delay)
if(mode)
usr << "<span class='warning'>There is already a vote in progress! please wait for it to finish.</span>"
to_chat(usr, "<span class='warning'>There is already a vote in progress! please wait for it to finish.</span>")
return 0
var/admin = FALSE
@@ -174,7 +174,7 @@ var/datum/subsystem/vote/SSvote
admin = TRUE
if(next_allowed_time > world.time && !admin)
usr << "<span class='warning'>A vote was initiated recently, you must wait roughly [(next_allowed_time-world.time)/10] seconds before a new vote can be started!</span>"
to_chat(usr, "<span class='warning'>A vote was initiated recently, you must wait roughly [(next_allowed_time-world.time)/10] seconds before a new vote can be started!</span>")
return 0
reset()
@@ -184,8 +184,7 @@ var/datum/subsystem/vote/SSvote
if("gamemode")
choices.Add(config.votable_modes)
if("roundtype")
choices.Add("secret")
choices.Add("extended")
choices.Add("secret","extended")
if("custom")
question = stripped_input(usr,"What is the vote for?")
if(!question)
@@ -204,7 +203,7 @@ var/datum/subsystem/vote/SSvote
if(mode == "custom")
text += "\n[question]"
log_vote(text)
world << "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>"
to_chat(world, "\n<font color='purple'><b>[text]</b>\nType <b>vote</b> or click <a href='?src=\ref[src]'>here</a> to place your votes.\nYou have [config.vote_period/10] seconds to vote.</font>")
time_remaining = round(config.vote_period/10)
for(var/c in clients)
var/client/C = c
@@ -216,7 +215,7 @@ var/datum/subsystem/vote/SSvote
return 1
return 0
/datum/subsystem/vote/proc/interface(client/C)
/datum/controller/subsystem/vote/proc/interface(client/C)
if(!C)
return
var/admin = 0
@@ -268,7 +267,7 @@ var/datum/subsystem/vote/SSvote
return .
/datum/subsystem/vote/Topic(href,href_list[],hsrc)
/datum/controller/subsystem/vote/Topic(href,href_list[],hsrc)
if(!usr || !usr.client)
return //not necessary but meh...just in-case somebody does something stupid
switch(href_list["vote"])
@@ -298,7 +297,7 @@ var/datum/subsystem/vote/SSvote
submit_vote(round(text2num(href_list["vote"])))
usr.vote()
/datum/subsystem/vote/proc/remove_action_buttons()
/datum/controller/subsystem/vote/proc/remove_action_buttons()
for(var/v in generated_actions)
var/datum/action/vote/V = v
if(!QDELETED(V))
+7 -7
View File
@@ -1,7 +1,7 @@
//Used for all kinds of weather, ex. lavaland ash storms.
var/datum/subsystem/weather/SSweather
/datum/subsystem/weather
var/datum/controller/subsystem/weather/SSweather
/datum/controller/subsystem/weather
name = "Weather"
flags = SS_BACKGROUND
wait = 10
@@ -9,10 +9,10 @@ var/datum/subsystem/weather/SSweather
var/list/existing_weather = list()
var/list/eligible_zlevels = list(ZLEVEL_LAVALAND)
/datum/subsystem/weather/New()
/datum/controller/subsystem/weather/New()
NEW_SS_GLOBAL(SSweather)
/datum/subsystem/weather/fire()
/datum/controller/subsystem/weather/fire()
for(var/V in processing)
var/datum/weather/W = V
if(W.aesthetic)
@@ -31,13 +31,13 @@ var/datum/subsystem/weather/SSweather
eligible_zlevels -= Z
addtimer(CALLBACK(src, .proc/make_z_eligible, Z), rand(3000, 6000) + W.weather_duration_upper, TIMER_UNIQUE) //Around 5-10 minutes between weathers
/datum/subsystem/weather/Initialize(start_timeofday)
/datum/controller/subsystem/weather/Initialize(start_timeofday)
..()
for(var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
new W //weather->New will handle adding itself to the list
/datum/subsystem/weather/proc/run_weather(weather_name, Z)
/datum/controller/subsystem/weather/proc/run_weather(weather_name, Z)
if(!weather_name)
return
for(var/V in existing_weather)
@@ -45,5 +45,5 @@ var/datum/subsystem/weather/SSweather
if(W.name == weather_name && W.target_z == Z)
W.telegraph()
/datum/subsystem/weather/proc/make_z_eligible(zlevel)
/datum/controller/subsystem/weather/proc/make_z_eligible(zlevel)
eligible_zlevels |= zlevel