Refactors weather into a subsystem (#19003)

Weather has been refactored from a weather control machine on the lavaland z-level into a subsystem. All existing weather has been changed to accommodate this change, and their code has been optimized by using addtimer() instead of sleep().

The new subsystem also supports adding weather to any z-level; for instance, if you made a weather called /datum/weather/rain_storm and made it target z-level 3 with a 100% probability, the rain storm would occur as much as possible with 5-10 minute intermissions. These intermissions take into account the weather's duration.
This commit is contained in:
Xhuis
2016-07-03 21:55:36 -04:00
committed by oranges
parent 1aa7a312c1
commit 2ab3f554d9
11 changed files with 322 additions and 275 deletions
+50
View File
@@ -0,0 +1,50 @@
//Used for all kinds of weather, ex. lavaland ash storms.
var/datum/subsystem/weather/SSweather
/datum/subsystem/weather
name = "Weather"
flags = SS_BACKGROUND
wait = 10
var/list/processing = list()
var/list/existing_weather = list()
var/list/eligible_zlevels = list(ZLEVEL_LAVALAND)
/datum/subsystem/weather/New()
NEW_SS_GLOBAL(SSweather)
/datum/subsystem/weather/fire()
for(var/V in processing)
var/datum/weather/W = V
if(W.aesthetic)
continue
for(var/mob/living/L in mob_list)
var/area/A = get_area(L)
if(L.z == W.target_z && !W.immunity_type in L.weather_immunities && A in W.impacted_areas)
W.impact(L)
for(var/Z in eligible_zlevels)
var/list/possible_weather_for_this_z = list()
for(var/V in existing_weather)
var/datum/weather/WE = V
if(WE.target_z == Z && WE.probability) //Another check so that it doesn't run extra weather
possible_weather_for_this_z[WE] = WE.probability
var/datum/weather/W = pickweight(possible_weather_for_this_z)
run_weather(W.name)
eligible_zlevels -= Z
addtimer(src, "make_z_eligible", rand(3000, 6000) + W.weather_duration_upper, Z) //Around 5-10 minutes between weathers
/datum/subsystem/weather/Initialize(start_timeofday)
..()
for(var/V in subtypesof(/datum/weather))
var/datum/weather/W = V
existing_weather |= new W
/datum/subsystem/weather/proc/run_weather(weather_name)
if(!weather_name)
return
for(var/V in existing_weather)
var/datum/weather/W = V
if(W.name == weather_name)
W.telegraph()
/datum/subsystem/weather/proc/make_z_eligible(zlevel)
eligible_zlevels |= zlevel