From a0a27219b68e593c8f437af7127f97cccc807329 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 10 May 2017 16:00:29 -0400 Subject: [PATCH 1/4] MC Runlevels --- code/__DEFINES/MC.dm | 5 +- code/__DEFINES/subsystems.dm | 11 +++ code/controllers/master.dm | 84 ++++++++++--------- code/controllers/subsystem.dm | 3 + code/controllers/subsystem/acid.dm | 1 + code/controllers/subsystem/air.dm | 1 + code/controllers/subsystem/augury.dm | 1 + code/controllers/subsystem/disease.dm | 1 + code/controllers/subsystem/events.dm | 2 + code/controllers/subsystem/fire_burning.dm | 1 + code/controllers/subsystem/garbage.dm | 3 +- code/controllers/subsystem/inbounds.dm | 2 + code/controllers/subsystem/mobs.dm | 1 + code/controllers/subsystem/npcpool.dm | 1 + code/controllers/subsystem/parallax.dm | 3 +- .../subsystem/processing/overlays.dm | 3 +- code/controllers/subsystem/server_maint.dm | 3 +- code/controllers/subsystem/shuttle.dm | 1 + code/controllers/subsystem/spacedrift.dm | 1 + code/controllers/subsystem/tgui.dm | 3 +- code/controllers/subsystem/ticker.dm | 10 ++- code/controllers/subsystem/time_track.dm | 3 +- code/controllers/subsystem/timer.dm | 2 +- code/controllers/subsystem/vote.dm | 4 +- code/controllers/subsystem/weather.dm | 2 + code/world.dm | 4 - 26 files changed, 98 insertions(+), 58 deletions(-) diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm index eb148e7b596..05c447d47cb 100644 --- a/code/__DEFINES/MC.dm +++ b/code/__DEFINES/MC.dm @@ -20,8 +20,9 @@ //SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier) +//deprecated, can be replaced //subsystem should fire during pre-game lobby. -#define SS_FIRE_IN_LOBBY 1 +//#define SS_FIRE_IN_LOBBY 1 //subsystem does not initialize. #define SS_NO_INIT 2 @@ -40,7 +41,7 @@ //Treat wait as a tick count, not DS, run every wait ticks. // (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems) -// (implies SS_FIRE_IN_LOBBY because of how it works) +// (implies all runlevels because of how it works) // (overrides SS_BACKGROUND) // This is designed for basically anything that works as a mini-mc (like SStimer) #define SS_TICKER 32 diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 79617db7bf9..ac6f4e4e7d8 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -60,3 +60,14 @@ #define INIT_ORDER_LIGHTING -20 #define INIT_ORDER_SQUEAK -40 #define INIT_ORDER_PERSISTENCE -100 + +// SS runlevels + +#define RUNLEVEL_INIT 0 +#define RUNLEVEL_LOBBY 1 +#define RUNLEVEL_SETUP 2 +#define RUNLEVEL_GAME 3 +#define RUNLEVEL_POSTGAME 4 + +#define RUNLEVEL_MIN_DEFAULT RUNLEVEL_SETUP +#define RUNLEVEL_MAX_DEFAULT RUNLEVEL_POSTGAME diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 01d0ac34470..602671f2db8 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -47,8 +47,6 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) var/make_runtime = 0 var/initializations_finished_with_no_players_logged_in //I wonder what this could be? - // Has round started? (So we know what subsystems to run) - var/local_round_started = FALSE //Don't read this var, use SSticker.HasRoundStarted() instead // The type of the last subsystem to be process()'d. var/last_type_processed @@ -59,6 +57,8 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) var/queue_priority_count_bg = 0 //Same, but for background subsystems var/map_loading = FALSE //Are we loading in a new map? + var/current_runlevel //for scheduling different subsystems for different stages of the round + /datum/controller/master/New() // Highlander-style: there can only be one! Kill off the old and replace it with the new. subsystems = list() @@ -176,6 +176,8 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) to_chat(world, "[msg]") log_world(msg) + SetRunLevel(1) + // Sort subsystems by display setting for easy access. sortTim(subsystems, /proc/cmp_subsystem_display) // Set world options. @@ -187,16 +189,9 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) // Loop. Master.StartProcessing(0) -// Notify the MC that the round has started. -/datum/controller/master/proc/RoundStart() - local_round_started = TRUE - var/timer = world.time - for (var/datum/controller/subsystem/SS in subsystems) - if (SS.flags & SS_FIRE_IN_LOBBY || SS.flags & SS_TICKER) - continue //already firing - // Stagger subsystems. - timer += world.tick_lag * rand(1, 5) - SS.next_fire = timer +/datum/controller/master/proc/SetRunLevel(runlevel) + testing("MC: Runlevel changed from [isnull(current_runlevel) ? "NULL" : current_runlevel] to [runlevel]") + current_runlevel = runlevel // Starts the mc, and sticks around to restart it if the loop ever ends. /datum/controller/master/proc/StartProcessing(delay) @@ -221,12 +216,9 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) //Prep the loop (most of this is because we want MC restarts to reset as much state as we can, and because // local vars rock - // Schedule the first run of the Subsystems. - local_round_started = world.has_round_started() //all this shit is here so that flag edits can be refreshed by restarting the MC. (and for speed) var/list/tickersubsystems = list() - var/list/normalsubsystems = list() - var/list/lobbysubsystems = list() + var/list/runlevel_sorted_subsystems = list(list()) //ensure we always have at least one runlevel var/timer = world.time for (var/thing in subsystems) var/datum/controller/subsystem/SS = thing @@ -241,25 +233,24 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) timer += world.tick_lag * rand(1, 5) SS.next_fire = timer continue - if (SS.flags & SS_FIRE_IN_LOBBY) - lobbysubsystems += SS - timer += world.tick_lag * rand(1, 5) - SS.next_fire = timer - else if (local_round_started) - timer += world.tick_lag * rand(1, 5) - SS.next_fire = timer - normalsubsystems += SS + var/ss_max_runlevel = SS.runlevel_max + while(runlevel_sorted_subsystems.len < ss_max_runlevel) + runlevel_sorted_subsystems += list(list()) + + for(var/I in SS.runlevel_min to ss_max_runlevel) + runlevel_sorted_subsystems[I] += SS queue_head = null queue_tail = null //these sort by lower priorities first to reduce the number of loops needed to add subsequent SS's to the queue //(higher subsystems will be sooner in the queue, adding them later in the loop means we don't have to loop thru them next queue add) sortTim(tickersubsystems, /proc/cmp_subsystem_priority) - sortTim(normalsubsystems, /proc/cmp_subsystem_priority) - sortTim(lobbysubsystems, /proc/cmp_subsystem_priority) - - normalsubsystems += tickersubsystems - lobbysubsystems += tickersubsystems + for(var/I in runlevel_sorted_subsystems) + sortTim(runlevel_sorted_subsystems, /proc/cmp_subsystem_priority) + I += tickersubsystems + + var/cached_runlevel = current_runlevel + var/list/current_runlevel_subsystems = runlevel_sorted_subsystems[cached_runlevel] init_timeofday = REALTIMEOFDAY init_time = world.time @@ -296,14 +287,23 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) if (!Failsafe || (Failsafe.processing_interval > 0 && (Failsafe.lasttick+(Failsafe.processing_interval*5)) < world.time)) new/datum/controller/failsafe() // (re)Start the failsafe. if (!queue_head || !(iteration % 3)) - if (local_round_started) - subsystems_to_check = normalsubsystems - else - subsystems_to_check = lobbysubsystems + var/checking_runlevel = current_runlevel + if(cached_runlevel != checking_runlevel) + //resechedule subsystems + cached_runlevel = checking_runlevel + current_runlevel_subsystems = runlevel_sorted_subsystems[cached_runlevel] + var/stagger = world.time + for(var/I in current_runlevel_subsystems) + var/datum/controller/subsystem/SS = I + if(SS.next_fire <= world.time) + stagger += world.tick_lag * rand(1, 5) + SS.next_fire = stagger + + subsystems_to_check = current_runlevel_subsystems else subsystems_to_check = tickersubsystems if (CheckQueue(subsystems_to_check) <= 0) - if (!SoftReset(tickersubsystems, normalsubsystems, lobbysubsystems)) + if (!SoftReset(tickersubsystems, runlevel_sorted_subsystems)) log_world("MC: SoftReset() failed, crashing") return if (!error_level) @@ -315,7 +315,7 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) if (queue_head) if (RunQueue() <= 0) - if (!SoftReset(tickersubsystems, normalsubsystems, lobbysubsystems)) + if (!SoftReset(tickersubsystems, runlevel_sorted_subsystems)) log_world("MC: SoftReset() failed, crashing") return if (!error_level) @@ -486,13 +486,15 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) //resets the queue, and all subsystems, while filtering out the subsystem lists // called if any mc's queue procs runtime or exit improperly. -/datum/controller/master/proc/SoftReset(list/ticker_SS, list/normal_SS, list/lobby_SS) +/datum/controller/master/proc/SoftReset(list/ticker_SS, list/runlevel_SS) . = 0 log_world("MC: SoftReset called, resetting MC queue state.") - if (!istype(subsystems) || !istype(ticker_SS) || !istype(normal_SS) || !istype(lobby_SS)) - log_world("MC: SoftReset: Bad list contents: '[subsystems]' '[ticker_SS]' '[normal_SS]' '[lobby_SS]' Crashing!") + if (!istype(subsystems) || !istype(ticker_SS) || !istype(runlevel_SS)) + log_world("MC: SoftReset: Bad list contents: '[subsystems]' '[ticker_SS]' '[runlevel_SS]'") return - var/subsystemstocheck = subsystems + ticker_SS + normal_SS + lobby_SS + var/subsystemstocheck = subsystems + ticker_SS + for(var/I in runlevel_SS) + subsystemstocheck |= I for (var/thing in subsystemstocheck) var/datum/controller/subsystem/SS = thing @@ -500,8 +502,8 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) //list(SS) is so if a list makes it in the subsystem list, we remove the list, not the contents subsystems -= list(SS) ticker_SS -= list(SS) - normal_SS -= list(SS) - lobby_SS -= list(SS) + for(var/I in runlevel_SS) + I -= list(SS) log_world("MC: SoftReset: Found bad entry in subsystem list, '[SS]'") continue if (SS.queue_next && !istype(SS.queue_next)) diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index f37a9159efd..dcc55a8cb0a 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -28,6 +28,9 @@ var/datum/controller/subsystem/queue_next var/datum/controller/subsystem/queue_prev + var/runlevel_min = RUNLEVEL_MIN_DEFAULT //the minimum runlevel at which this subsystem will fire + var/runlevel_max = RUNLEVEL_MAX_DEFAULT //the maximum runlevel at which this subsystem will fire + var/static/failure_strikes = 0 //How many times we suspect this subsystem has crashed the MC, 3 strikes and you're out! //Do not override diff --git a/code/controllers/subsystem/acid.dm b/code/controllers/subsystem/acid.dm index a0a506499fd..765c8cd49d0 100644 --- a/code/controllers/subsystem/acid.dm +++ b/code/controllers/subsystem/acid.dm @@ -2,6 +2,7 @@ SUBSYSTEM_DEF(acid) name = "Acid" priority = 40 flags = SS_NO_INIT|SS_BACKGROUND + runlevel_min = RUNLEVEL_GAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 38245c5bccf..0b77bbdc06a 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -12,6 +12,7 @@ SUBSYSTEM_DEF(air) priority = 20 wait = 5 flags = SS_BACKGROUND + runlevel_min = RUNLEVEL_GAME var/cost_turfs = 0 var/cost_groups = 0 diff --git a/code/controllers/subsystem/augury.dm b/code/controllers/subsystem/augury.dm index 851234fde57..2ac9e05356f 100644 --- a/code/controllers/subsystem/augury.dm +++ b/code/controllers/subsystem/augury.dm @@ -1,6 +1,7 @@ SUBSYSTEM_DEF(augury) name = "Augury" flags = SS_NO_INIT + runlevel_min = RUNLEVEL_GAME var/list/watchers = list() var/list/doombringers = list() diff --git a/code/controllers/subsystem/disease.dm b/code/controllers/subsystem/disease.dm index 8b867146a66..845238f497a 100644 --- a/code/controllers/subsystem/disease.dm +++ b/code/controllers/subsystem/disease.dm @@ -1,6 +1,7 @@ SUBSYSTEM_DEF(disease) name = "Disease" flags = SS_KEEP_TIMING|SS_NO_INIT + runlevel_min = RUNLEVEL_GAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index b99b71ed336..22e3485bb7e 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -1,6 +1,8 @@ SUBSYSTEM_DEF(events) name = "Events" init_order = INIT_ORDER_EVENTS + runlevel_min = RUNLEVEL_GAME + runlevel_max = RUNLEVEL_GAME var/list/control = list() //list of all datum/round_event_control. Used for selecting events based on weight and occurrences. var/list/running = list() //list of all existing /datum/round_event diff --git a/code/controllers/subsystem/fire_burning.dm b/code/controllers/subsystem/fire_burning.dm index af3cb3f6a1c..4cba46a0aa4 100644 --- a/code/controllers/subsystem/fire_burning.dm +++ b/code/controllers/subsystem/fire_burning.dm @@ -2,6 +2,7 @@ SUBSYSTEM_DEF(fire_burning) name = "Fire Burning" priority = 40 flags = SS_NO_INIT|SS_BACKGROUND + runlevel_min = RUNLEVEL_GAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 7d3682cf5f7..69a16215826 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -2,7 +2,8 @@ SUBSYSTEM_DEF(garbage) name = "Garbage" priority = 15 wait = 5 - flags = SS_FIRE_IN_LOBBY|SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT + flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT + runlevel_min = RUNLEVEL_LOBBY var/collection_timeout = 3000// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object var/delslasttick = 0 // number of del()'s we've done this tick diff --git a/code/controllers/subsystem/inbounds.dm b/code/controllers/subsystem/inbounds.dm index 1ac9115982b..dccb6e45ebe 100644 --- a/code/controllers/subsystem/inbounds.dm +++ b/code/controllers/subsystem/inbounds.dm @@ -2,6 +2,8 @@ SUBSYSTEM_DEF(inbounds) name = "Inbounds" priority = 40 flags = SS_NO_INIT + runlevel_min = RUNLEVEL_GAME + runlevel_max = RUNLEVEL_GAME var/list/processing = list() var/list/currentrun = list() diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index f87b94bac48..c7a6fb883e0 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -2,6 +2,7 @@ SUBSYSTEM_DEF(mobs) name = "Mobs" priority = 100 flags = SS_KEEP_TIMING|SS_NO_INIT + runlevel_min = RUNLEVEL_GAME var/list/currentrun = list() diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm index 77838e6509f..5a7c263034a 100644 --- a/code/controllers/subsystem/npcpool.dm +++ b/code/controllers/subsystem/npcpool.dm @@ -7,6 +7,7 @@ SUBSYSTEM_DEF(npcpool) name = "NPC Pool" flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND priority = 20 + runlevel_min = RUNLEVEL_GAME var/list/canBeUsed = list() var/list/needsDelegate = list() diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index 6ce2928f895..37a398d5d86 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -1,8 +1,9 @@ SUBSYSTEM_DEF(parallax) name = "Parallax" wait = 2 - flags = SS_POST_FIRE_TIMING | SS_FIRE_IN_LOBBY | SS_BACKGROUND | SS_NO_INIT + flags = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT priority = 65 + runlevel_min = RUNLEVEL_LOBBY var/list/currentrun /datum/controller/subsystem/parallax/fire(resumed = 0) diff --git a/code/controllers/subsystem/processing/overlays.dm b/code/controllers/subsystem/processing/overlays.dm index 1aa76e6b3de..3484571c5f5 100644 --- a/code/controllers/subsystem/processing/overlays.dm +++ b/code/controllers/subsystem/processing/overlays.dm @@ -1,9 +1,10 @@ PROCESSING_SUBSYSTEM_DEF(overlays) name = "Overlay" - flags = SS_TICKER|SS_FIRE_IN_LOBBY + flags = SS_TICKER wait = 1 priority = 500 init_order = INIT_ORDER_OVERLAY + runlevel_min = RUNLEVEL_LOBBY stat_tag = "Ov" currentrun = null diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index c248ca0a98e..b69188d1477 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -3,8 +3,9 @@ SUBSYSTEM_DEF(server_maint) name = "Server Tasks" wait = 6 - flags = SS_POST_FIRE_TIMING|SS_FIRE_IN_LOBBY + flags = SS_POST_FIRE_TIMING priority = 10 + runlevel_min = RUNLEVEL_LOBBY var/list/currentrun /datum/controller/subsystem/server_maint/Initialize(timeofday) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index dcddd37fbfe..d23d0a0111a 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -5,6 +5,7 @@ SUBSYSTEM_DEF(shuttle) wait = 10 init_order = INIT_ORDER_SHUTTLE flags = SS_KEEP_TIMING|SS_NO_TICK_CHECK + runlevel_max = RUNLEVEL_GAME var/list/mobile = list() var/list/stationary = list() diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm index c6d12d2efbc..b3b530611a6 100644 --- a/code/controllers/subsystem/spacedrift.dm +++ b/code/controllers/subsystem/spacedrift.dm @@ -3,6 +3,7 @@ SUBSYSTEM_DEF(spacedrift) priority = 30 wait = 5 flags = SS_NO_INIT|SS_KEEP_TIMING + runlevel_min = RUNLEVEL_GAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index 862dfb0f98d..2f2e80f16f3 100644 --- a/code/controllers/subsystem/tgui.dm +++ b/code/controllers/subsystem/tgui.dm @@ -1,8 +1,9 @@ SUBSYSTEM_DEF(tgui) name = "tgui" wait = 9 - flags = SS_NO_INIT|SS_FIRE_IN_LOBBY + flags = SS_NO_INIT priority = 110 + runlevel_min = RUNLEVEL_LOBBY var/list/currentrun = list() var/list/open_uis = list() // A list of open UIs, grouped by src_object and ui_key. diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index e1c751ce550..d3f0176dd8f 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -5,7 +5,9 @@ SUBSYSTEM_DEF(ticker) init_order = INIT_ORDER_TICKER priority = 200 - flags = SS_FIRE_IN_LOBBY|SS_KEEP_TIMING + flags = SS_KEEP_TIMING + runlevel_min = RUNLEVEL_LOBBY + runlevel_max = RUNLEVEL_GAME var/current_state = GAME_STATE_STARTUP //state of current round (used by process()) Use the defines GAME_STATE_* ! var/force_ending = 0 //Round was ended by admin intervention @@ -105,6 +107,7 @@ SUBSYSTEM_DEF(ticker) if(timeLeft <= 0) current_state = GAME_STATE_SETTING_UP + Master.SetRunLevel(RUNLEVEL_SETUP) if(start_immediately) fire() @@ -112,6 +115,7 @@ SUBSYSTEM_DEF(ticker) if(!setup()) //setup failed current_state = GAME_STATE_STARTUP + Master.SetRunLevel(RUNLEVEL_LOBBY) if(GAME_STATE_PLAYING) mode.process(wait * 0.1) @@ -123,6 +127,7 @@ SUBSYSTEM_DEF(ticker) current_state = GAME_STATE_FINISHED toggle_ooc(1) // Turn it on declare_completion(force_ending) + Master.SetRunLevel(RUNLEVEL_POSTGAME) /datum/controller/subsystem/ticker/proc/setup() to_chat(world, "Starting game...") @@ -198,8 +203,6 @@ SUBSYSTEM_DEF(ticker) GLOB.data_core.manifest() transfer_characters() //transfer keys to the new mobs - - Master.RoundStart() //let the party begin... for(var/I in round_start_events) var/datum/callback/cb = I @@ -213,6 +216,7 @@ SUBSYSTEM_DEF(ticker) world << sound('sound/AI/welcome.ogg') current_state = GAME_STATE_PLAYING + Master.SetRunLevel(RUNLEVEL_GAME) if(SSevents.holidays) to_chat(world, "and...") diff --git a/code/controllers/subsystem/time_track.dm b/code/controllers/subsystem/time_track.dm index 20230037c2d..1e82057dbf9 100644 --- a/code/controllers/subsystem/time_track.dm +++ b/code/controllers/subsystem/time_track.dm @@ -1,7 +1,8 @@ SUBSYSTEM_DEF(time_track) name = "Time Tracking" wait = 600 - flags = SS_NO_INIT|SS_FIRE_IN_LOBBY|SS_NO_TICK_CHECK + flags = SS_NO_INIT|SS_NO_TICK_CHECK + runlevel_min = RUNLEVEL_LOBBY var/time_dilation_current = 0 diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index 55ebbfa3524..2203e0f1f5c 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -6,7 +6,7 @@ SUBSYSTEM_DEF(timer) wait = 1 //SS_TICKER subsystem, so wait is in ticks init_order = INIT_ORDER_TIMER - flags = SS_FIRE_IN_LOBBY|SS_TICKER|SS_NO_INIT + flags = SS_TICKER|SS_NO_INIT var/list/datum/timedevent/processing = list() var/list/hashes = list() diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 5abea8281a1..77d4d07afbc 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -2,7 +2,9 @@ SUBSYSTEM_DEF(vote) name = "Vote" wait = 10 - flags = SS_FIRE_IN_LOBBY|SS_KEEP_TIMING|SS_NO_INIT + flags = SS_KEEP_TIMING|SS_NO_INIT + + runlevel_min = RUNLEVEL_LOBBY var/initiator = null var/started_time = null diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm index 569eb4032c7..6245aa927f8 100644 --- a/code/controllers/subsystem/weather.dm +++ b/code/controllers/subsystem/weather.dm @@ -3,6 +3,8 @@ SUBSYSTEM_DEF(weather) name = "Weather" flags = SS_BACKGROUND wait = 10 + runlevel_min = RUNLEVEL_GAME + runlevel_max = RUNLEVEL_GAME var/list/processing = list() var/list/existing_weather = list() var/list/eligible_zlevels = list(ZLEVEL_LAVALAND) diff --git a/code/world.dm b/code/world.dm index 353d8198183..89f2d9a0dc4 100644 --- a/code/world.dm +++ b/code/world.dm @@ -341,7 +341,3 @@ s += ": [jointext(features, ", ")]" status = s - - -/world/proc/has_round_started() - return SSticker.HasRoundStarted() From 72f171495ad2df5601f055cc316d11ed7b94eb5b Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 11 May 2017 09:46:47 -0400 Subject: [PATCH 2/4] Adds a list of bitflags --- code/__DEFINES/flags.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index ac40dc75590..a0516bfd5c6 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -4,6 +4,8 @@ #define ALL ~0 //For convenience. #define NONE 0 +GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768)) + //FLAGS BITMASK #define STOPSPRESSUREDMAGE 1 //This flag is used on the flags variable for SUIT and HEAD items which stop pressure damage. Note that the flag 1 was previous used as ONBACK, so it is possible for some code to use (flags & 1) when checking if something can be put on your back. Replace this code with (inv_flags & SLOT_BACK) if you see it anywhere //To successfully stop you taking all pressure damage you must have both a suit and head item with this flag. From 1c6bd654b7717601771eb55ecf8baae14032b0e2 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Thu, 11 May 2017 10:04:19 -0400 Subject: [PATCH 3/4] Make runlevels bitflags --- code/__DEFINES/subsystems.dm | 7 +++---- code/controllers/master.dm | 15 ++++++++++----- code/controllers/subsystem.dm | 3 +-- code/controllers/subsystem/acid.dm | 2 +- code/controllers/subsystem/air.dm | 2 +- code/controllers/subsystem/augury.dm | 2 +- code/controllers/subsystem/disease.dm | 2 +- code/controllers/subsystem/events.dm | 3 +-- code/controllers/subsystem/fire_burning.dm | 2 +- code/controllers/subsystem/garbage.dm | 2 +- code/controllers/subsystem/inbounds.dm | 3 +-- code/controllers/subsystem/mobs.dm | 2 +- code/controllers/subsystem/npcpool.dm | 2 +- code/controllers/subsystem/parallax.dm | 2 +- code/controllers/subsystem/processing/overlays.dm | 2 +- code/controllers/subsystem/server_maint.dm | 2 +- code/controllers/subsystem/shuttle.dm | 2 +- code/controllers/subsystem/spacedrift.dm | 2 +- code/controllers/subsystem/tgui.dm | 2 +- code/controllers/subsystem/throwing.dm | 1 + code/controllers/subsystem/ticker.dm | 3 +-- code/controllers/subsystem/time_track.dm | 2 +- code/controllers/subsystem/vote.dm | 2 +- code/controllers/subsystem/weather.dm | 3 +-- 24 files changed, 35 insertions(+), 35 deletions(-) diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index ac6f4e4e7d8..9a0bf8d401e 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -66,8 +66,7 @@ #define RUNLEVEL_INIT 0 #define RUNLEVEL_LOBBY 1 #define RUNLEVEL_SETUP 2 -#define RUNLEVEL_GAME 3 -#define RUNLEVEL_POSTGAME 4 +#define RUNLEVEL_GAME 4 +#define RUNLEVEL_POSTGAME 8 -#define RUNLEVEL_MIN_DEFAULT RUNLEVEL_SETUP -#define RUNLEVEL_MAX_DEFAULT RUNLEVEL_POSTGAME +#define RUNLEVELS_DEFAULT (RUNLEVEL_SETUP | RUNLEVEL_GAME | RUNLEVEL_POSTGAME) \ No newline at end of file diff --git a/code/controllers/master.dm b/code/controllers/master.dm index 602671f2db8..ed05e62ed29 100644 --- a/code/controllers/master.dm +++ b/code/controllers/master.dm @@ -233,12 +233,17 @@ GLOBAL_VAR_INIT(CURRENT_TICKLIMIT, TICK_LIMIT_RUNNING) timer += world.tick_lag * rand(1, 5) SS.next_fire = timer continue - var/ss_max_runlevel = SS.runlevel_max - while(runlevel_sorted_subsystems.len < ss_max_runlevel) - runlevel_sorted_subsystems += list(list()) - for(var/I in SS.runlevel_min to ss_max_runlevel) - runlevel_sorted_subsystems[I] += SS + var/ss_runlevels = SS.runlevels + var/added_to_any = FALSE + for(var/I in 1 to GLOB.bitflags.len) + if(ss_runlevels & GLOB.bitflags[I]) + while(runlevel_sorted_subsystems.len < I) + runlevel_sorted_subsystems += list(list()) + runlevel_sorted_subsystems[I] += SS + added_to_any = TRUE + if(!added_to_any) + WARNING("[SS.name] subsystem is not SS_NO_FIRE but also does not have any runlevels set!") queue_head = null queue_tail = null diff --git a/code/controllers/subsystem.dm b/code/controllers/subsystem.dm index dcc55a8cb0a..50d5ea2070b 100644 --- a/code/controllers/subsystem.dm +++ b/code/controllers/subsystem.dm @@ -28,8 +28,7 @@ var/datum/controller/subsystem/queue_next var/datum/controller/subsystem/queue_prev - var/runlevel_min = RUNLEVEL_MIN_DEFAULT //the minimum runlevel at which this subsystem will fire - var/runlevel_max = RUNLEVEL_MAX_DEFAULT //the maximum runlevel at which this subsystem will fire + var/runlevels = RUNLEVELS_DEFAULT //points of the game at which the SS can fire var/static/failure_strikes = 0 //How many times we suspect this subsystem has crashed the MC, 3 strikes and you're out! diff --git a/code/controllers/subsystem/acid.dm b/code/controllers/subsystem/acid.dm index 765c8cd49d0..a83afb3923b 100644 --- a/code/controllers/subsystem/acid.dm +++ b/code/controllers/subsystem/acid.dm @@ -2,7 +2,7 @@ SUBSYSTEM_DEF(acid) name = "Acid" priority = 40 flags = SS_NO_INIT|SS_BACKGROUND - runlevel_min = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index 0b77bbdc06a..e9dc5329754 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -12,7 +12,7 @@ SUBSYSTEM_DEF(air) priority = 20 wait = 5 flags = SS_BACKGROUND - runlevel_min = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/cost_turfs = 0 var/cost_groups = 0 diff --git a/code/controllers/subsystem/augury.dm b/code/controllers/subsystem/augury.dm index 2ac9e05356f..32086f52ed6 100644 --- a/code/controllers/subsystem/augury.dm +++ b/code/controllers/subsystem/augury.dm @@ -1,7 +1,7 @@ SUBSYSTEM_DEF(augury) name = "Augury" flags = SS_NO_INIT - runlevel_min = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/watchers = list() var/list/doombringers = list() diff --git a/code/controllers/subsystem/disease.dm b/code/controllers/subsystem/disease.dm index 845238f497a..5499680a2f1 100644 --- a/code/controllers/subsystem/disease.dm +++ b/code/controllers/subsystem/disease.dm @@ -1,7 +1,7 @@ SUBSYSTEM_DEF(disease) name = "Disease" flags = SS_KEEP_TIMING|SS_NO_INIT - runlevel_min = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 22e3485bb7e..5e557b32d58 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -1,8 +1,7 @@ SUBSYSTEM_DEF(events) name = "Events" init_order = INIT_ORDER_EVENTS - runlevel_min = RUNLEVEL_GAME - runlevel_max = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME var/list/control = list() //list of all datum/round_event_control. Used for selecting events based on weight and occurrences. var/list/running = list() //list of all existing /datum/round_event diff --git a/code/controllers/subsystem/fire_burning.dm b/code/controllers/subsystem/fire_burning.dm index 4cba46a0aa4..73358000f16 100644 --- a/code/controllers/subsystem/fire_burning.dm +++ b/code/controllers/subsystem/fire_burning.dm @@ -2,7 +2,7 @@ SUBSYSTEM_DEF(fire_burning) name = "Fire Burning" priority = 40 flags = SS_NO_INIT|SS_BACKGROUND - runlevel_min = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/controllers/subsystem/garbage.dm b/code/controllers/subsystem/garbage.dm index 69a16215826..628c6a14eac 100644 --- a/code/controllers/subsystem/garbage.dm +++ b/code/controllers/subsystem/garbage.dm @@ -3,7 +3,7 @@ SUBSYSTEM_DEF(garbage) priority = 15 wait = 5 flags = SS_POST_FIRE_TIMING|SS_BACKGROUND|SS_NO_INIT - runlevel_min = RUNLEVEL_LOBBY + runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY var/collection_timeout = 3000// deciseconds to wait to let running procs finish before we just say fuck it and force del() the object var/delslasttick = 0 // number of del()'s we've done this tick diff --git a/code/controllers/subsystem/inbounds.dm b/code/controllers/subsystem/inbounds.dm index dccb6e45ebe..16e0f53028c 100644 --- a/code/controllers/subsystem/inbounds.dm +++ b/code/controllers/subsystem/inbounds.dm @@ -2,8 +2,7 @@ SUBSYSTEM_DEF(inbounds) name = "Inbounds" priority = 40 flags = SS_NO_INIT - runlevel_min = RUNLEVEL_GAME - runlevel_max = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME var/list/processing = list() var/list/currentrun = list() diff --git a/code/controllers/subsystem/mobs.dm b/code/controllers/subsystem/mobs.dm index c7a6fb883e0..cbe9d5c2450 100644 --- a/code/controllers/subsystem/mobs.dm +++ b/code/controllers/subsystem/mobs.dm @@ -2,7 +2,7 @@ SUBSYSTEM_DEF(mobs) name = "Mobs" priority = 100 flags = SS_KEEP_TIMING|SS_NO_INIT - runlevel_min = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() diff --git a/code/controllers/subsystem/npcpool.dm b/code/controllers/subsystem/npcpool.dm index 5a7c263034a..e88da7d9009 100644 --- a/code/controllers/subsystem/npcpool.dm +++ b/code/controllers/subsystem/npcpool.dm @@ -7,7 +7,7 @@ SUBSYSTEM_DEF(npcpool) name = "NPC Pool" flags = SS_POST_FIRE_TIMING|SS_NO_INIT|SS_BACKGROUND priority = 20 - runlevel_min = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/canBeUsed = list() var/list/needsDelegate = list() diff --git a/code/controllers/subsystem/parallax.dm b/code/controllers/subsystem/parallax.dm index 37a398d5d86..39d07ee676b 100644 --- a/code/controllers/subsystem/parallax.dm +++ b/code/controllers/subsystem/parallax.dm @@ -3,7 +3,7 @@ SUBSYSTEM_DEF(parallax) wait = 2 flags = SS_POST_FIRE_TIMING | SS_BACKGROUND | SS_NO_INIT priority = 65 - runlevel_min = RUNLEVEL_LOBBY + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT var/list/currentrun /datum/controller/subsystem/parallax/fire(resumed = 0) diff --git a/code/controllers/subsystem/processing/overlays.dm b/code/controllers/subsystem/processing/overlays.dm index 3484571c5f5..4e1d2d64d51 100644 --- a/code/controllers/subsystem/processing/overlays.dm +++ b/code/controllers/subsystem/processing/overlays.dm @@ -4,7 +4,7 @@ PROCESSING_SUBSYSTEM_DEF(overlays) wait = 1 priority = 500 init_order = INIT_ORDER_OVERLAY - runlevel_min = RUNLEVEL_LOBBY + runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_SETUP stat_tag = "Ov" currentrun = null diff --git a/code/controllers/subsystem/server_maint.dm b/code/controllers/subsystem/server_maint.dm index b69188d1477..a24d952b9dc 100644 --- a/code/controllers/subsystem/server_maint.dm +++ b/code/controllers/subsystem/server_maint.dm @@ -5,7 +5,7 @@ SUBSYSTEM_DEF(server_maint) wait = 6 flags = SS_POST_FIRE_TIMING priority = 10 - runlevel_min = RUNLEVEL_LOBBY + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT var/list/currentrun /datum/controller/subsystem/server_maint/Initialize(timeofday) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index d23d0a0111a..dc91b0f4d56 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -5,7 +5,7 @@ SUBSYSTEM_DEF(shuttle) wait = 10 init_order = INIT_ORDER_SHUTTLE flags = SS_KEEP_TIMING|SS_NO_TICK_CHECK - runlevel_max = RUNLEVEL_GAME + runlevels = RUNLEVEL_SETUP | RUNLEVEL_GAME var/list/mobile = list() var/list/stationary = list() diff --git a/code/controllers/subsystem/spacedrift.dm b/code/controllers/subsystem/spacedrift.dm index b3b530611a6..8fe7cbe048f 100644 --- a/code/controllers/subsystem/spacedrift.dm +++ b/code/controllers/subsystem/spacedrift.dm @@ -3,7 +3,7 @@ SUBSYSTEM_DEF(spacedrift) priority = 30 wait = 5 flags = SS_NO_INIT|SS_KEEP_TIMING - runlevel_min = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun = list() var/list/processing = list() diff --git a/code/controllers/subsystem/tgui.dm b/code/controllers/subsystem/tgui.dm index 2f2e80f16f3..52fd286eedb 100644 --- a/code/controllers/subsystem/tgui.dm +++ b/code/controllers/subsystem/tgui.dm @@ -3,7 +3,7 @@ SUBSYSTEM_DEF(tgui) wait = 9 flags = SS_NO_INIT priority = 110 - runlevel_min = RUNLEVEL_LOBBY + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT var/list/currentrun = list() var/list/open_uis = list() // A list of open UIs, grouped by src_object and ui_key. diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 8d95d3fa294..4ae31e98d65 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -6,6 +6,7 @@ SUBSYSTEM_DEF(throwing) priority = 25 wait = 1 flags = SS_NO_INIT|SS_KEEP_TIMING|SS_TICKER + runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME var/list/currentrun var/list/processing = list() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index d3f0176dd8f..854baefaf7a 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -6,8 +6,7 @@ SUBSYSTEM_DEF(ticker) priority = 200 flags = SS_KEEP_TIMING - runlevel_min = RUNLEVEL_LOBBY - runlevel_max = RUNLEVEL_GAME + runlevels = RUNLEVEL_LOBBY | RUNLEVEL_SETUP | RUNLEVEL_GAME var/current_state = GAME_STATE_STARTUP //state of current round (used by process()) Use the defines GAME_STATE_* ! var/force_ending = 0 //Round was ended by admin intervention diff --git a/code/controllers/subsystem/time_track.dm b/code/controllers/subsystem/time_track.dm index 1e82057dbf9..cb190206b7d 100644 --- a/code/controllers/subsystem/time_track.dm +++ b/code/controllers/subsystem/time_track.dm @@ -2,7 +2,7 @@ SUBSYSTEM_DEF(time_track) name = "Time Tracking" wait = 600 flags = SS_NO_INIT|SS_NO_TICK_CHECK - runlevel_min = RUNLEVEL_LOBBY + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT var/time_dilation_current = 0 diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 77d4d07afbc..a914074a418 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -4,7 +4,7 @@ SUBSYSTEM_DEF(vote) flags = SS_KEEP_TIMING|SS_NO_INIT - runlevel_min = RUNLEVEL_LOBBY + runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT var/initiator = null var/started_time = null diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm index 6245aa927f8..88102e260cb 100644 --- a/code/controllers/subsystem/weather.dm +++ b/code/controllers/subsystem/weather.dm @@ -3,8 +3,7 @@ SUBSYSTEM_DEF(weather) name = "Weather" flags = SS_BACKGROUND wait = 10 - runlevel_min = RUNLEVEL_GAME - runlevel_max = RUNLEVEL_GAME + runlevels = RUNLEVEL_GAME var/list/processing = list() var/list/existing_weather = list() var/list/eligible_zlevels = list(ZLEVEL_LAVALAND) From 1cfda170f83c7ac90e70ea22e50665c51734115c Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Fri, 12 May 2017 10:19:56 -0400 Subject: [PATCH 4/4] Shifts SS defines --- code/__DEFINES/MC.dm | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/code/__DEFINES/MC.dm b/code/__DEFINES/MC.dm index 05c447d47cb..2a08786161e 100644 --- a/code/__DEFINES/MC.dm +++ b/code/__DEFINES/MC.dm @@ -20,40 +20,36 @@ //SubSystem flags (Please design any new flags so that the default is off, to make adding flags to subsystems easier) -//deprecated, can be replaced -//subsystem should fire during pre-game lobby. -//#define SS_FIRE_IN_LOBBY 1 - //subsystem does not initialize. -#define SS_NO_INIT 2 +#define SS_NO_INIT 1 //subsystem does not fire. // (like can_fire = 0, but keeps it from getting added to the processing subsystems list) // (Requires a MC restart to change) -#define SS_NO_FIRE 4 +#define SS_NO_FIRE 2 //subsystem only runs on spare cpu (after all non-background subsystems have ran that tick) // SS_BACKGROUND has its own priority bracket -#define SS_BACKGROUND 8 +#define SS_BACKGROUND 4 //subsystem does not tick check, and should not run unless there is enough time (or its running behind (unless background)) -#define SS_NO_TICK_CHECK 16 +#define SS_NO_TICK_CHECK 8 //Treat wait as a tick count, not DS, run every wait ticks. // (also forces it to run first in the tick, above even SS_NO_TICK_CHECK subsystems) // (implies all runlevels because of how it works) // (overrides SS_BACKGROUND) // This is designed for basically anything that works as a mini-mc (like SStimer) -#define SS_TICKER 32 +#define SS_TICKER 16 //keep the subsystem's timing on point by firing early if it fired late last fire because of lag // ie: if a 20ds subsystem fires say 5 ds late due to lag or what not, its next fire would be in 15ds, not 20ds. -#define SS_KEEP_TIMING 64 +#define SS_KEEP_TIMING 32 //Calculate its next fire after its fired. // (IE: if a 5ds wait SS takes 2ds to run, its next fire should be 5ds away, not 3ds like it normally would be) // This flag overrides SS_KEEP_TIMING -#define SS_POST_FIRE_TIMING 128 +#define SS_POST_FIRE_TIMING 64 //SUBSYSTEM STATES #define SS_IDLE 0 //aint doing shit.