diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm
new file mode 100644
index 00000000000..5ec40fa14e1
--- /dev/null
+++ b/code/controllers/subsystem/weather.dm
@@ -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
diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm
new file mode 100644
index 00000000000..a6dcc27a4ea
--- /dev/null
+++ b/code/datums/weather/weather.dm
@@ -0,0 +1,125 @@
+//The effects of weather occur across an entire z-level. For instance, lavaland has periodic ash storms that scorch most unprotected creatures.
+
+#define STARTUP_STAGE 1
+#define MAIN_STAGE 2
+#define WIND_DOWN_STAGE 3
+#define END_STAGE 4
+
+/datum/weather
+ var/name = "space wind"
+ var/desc = "Heavy gusts of wind blanket the area, periodically knocking down anyone caught in the open."
+
+ var/telegraph_message = "The wind begins to pick up." //The message displayed in chat to foreshadow the weather's beginning
+ var/telegraph_duration = 300 //In deciseconds, how long from the beginning of the telegraph until the weather begins
+ var/telegraph_sound //The sound file played to everyone on an affected z-level
+ var/telegraph_overlay //The overlay applied to all tiles on the z-level
+
+ var/weather_message = "The wind begins to blow ferociously!" //Displayed in chat once the weather begins in earnest
+ var/weather_duration = 1200 //In deciseconds, how long the weather lasts once it begins
+ var/weather_duration_lower = 1200 //See above - this is the lowest possible duration
+ var/weather_duration_upper = 1500 //See above - this is the highest possible duration
+ var/weather_sound
+ var/weather_overlay
+
+ var/end_message = "The wind relents its assault." //Displayed once the wather is over
+ var/end_duration = 300 //In deciseconds, how long the "wind-down" graphic will appear before vanishing entirely
+ var/end_sound
+ var/end_overlay
+
+ var/area_type = /area/space //Types of area to affect
+ var/list/impacted_areas = list() //Areas to be affected by the weather, calculated when the weather begins
+ var/target_z = ZLEVEL_STATION //The z-level to affect
+
+ var/overlay_layer = AREA_LAYER //Since it's above everything else, this is the layer used by default. TURF_LAYER is below mobs and walls if you need to use that.
+ var/aesthetic = FALSE //If the weather has no purpose other than looks
+ var/immunity_type = "storm" //Used by mobs to prevent them from being affected by the weather
+
+ var/stage = END_STAGE //The stage of the weather, from 1-4
+
+ var/probability = FALSE //Percent chance to happen if there are other possible weathers on the z-level
+
+/datum/weather/New()
+ ..()
+ SSweather.existing_weather |= src
+
+/datum/weather/Destroy()
+ SSweather.existing_weather -= src
+ ..()
+
+/datum/weather/proc/telegraph()
+ if(stage == STARTUP_STAGE)
+ return
+ stage = STARTUP_STAGE
+ for(var/V in get_areas(area_type))
+ var/area/A = V
+ if(A.z == target_z)
+ impacted_areas |= A
+ weather_duration = rand(weather_duration_lower, weather_duration_upper)
+ update_areas()
+ for(var/V in player_list)
+ var/mob/M = V
+ if(M.z == target_z)
+ if(telegraph_message)
+ M << telegraph_message
+ if(telegraph_sound)
+ M << sound(telegraph_sound)
+ addtimer(src, "start", telegraph_duration)
+
+/datum/weather/proc/start()
+ if(stage >= MAIN_STAGE)
+ return
+ stage = MAIN_STAGE
+ update_areas()
+ for(var/V in player_list)
+ var/mob/M = V
+ if(M.z == target_z)
+ if(weather_message)
+ M << weather_message
+ if(weather_sound)
+ M << sound(weather_sound)
+ START_PROCESSING(SSweather, src)
+ addtimer(src, "wind_down", weather_duration)
+
+/datum/weather/proc/wind_down()
+ if(stage >= WIND_DOWN_STAGE)
+ return
+ stage = WIND_DOWN_STAGE
+ update_areas()
+ for(var/V in player_list)
+ var/mob/M = V
+ if(M.z == target_z)
+ if(end_message)
+ M << end_message
+ if(end_sound)
+ M << sound(end_sound)
+ STOP_PROCESSING(SSweather, src)
+ addtimer(src, "end", end_duration)
+
+/datum/weather/proc/end()
+ if(stage == END_STAGE)
+ return
+ stage = END_STAGE
+ update_areas()
+
+/datum/weather/proc/impact(mob/living/L) //What effect does this weather have on the hapless mob?
+ return
+
+/datum/weather/proc/update_areas()
+ for(var/V in impacted_areas)
+ var/area/N = V
+ N.layer = overlay_layer
+ N.icon = 'icons/effects/weather_effects.dmi'
+ N.invisibility = 0
+ switch(stage)
+ if(STARTUP_STAGE)
+ N.icon_state = telegraph_overlay
+ if(MAIN_STAGE)
+ N.icon_state = weather_overlay
+ if(WIND_DOWN_STAGE)
+ N.icon_state = end_overlay
+ if(END_STAGE)
+ N.icon_state = initial(N.icon_state)
+ N.icon = 'icons/turf/areas.dmi'
+ N.layer = AREA_LAYER //Just default back to normal area stuff since I assume setting a var is faster than initial
+ N.invisibility = INVISIBILITY_MAXIMUM
+ N.opacity = 0
diff --git a/code/datums/weather/weather_types.dm b/code/datums/weather/weather_types.dm
new file mode 100644
index 00000000000..683fee7b0ae
--- /dev/null
+++ b/code/datums/weather/weather_types.dm
@@ -0,0 +1,113 @@
+//Different types of weather.
+
+/datum/weather/floor_is_lava //The Floor is Lava: Makes all turfs damage anyone on them unless they're standing on a solid object.
+ name = "the floor is lava"
+ desc = "The ground turns into surprisingly cool lava, lightly damaging anything on the floor."
+
+ telegraph_message = "Waves of heat emanate from the ground..."
+ telegraph_duration = 150
+
+ weather_message = "The floor is lava! Get on top of something!"
+ weather_duration_lower = 300
+ weather_duration_upper = 600
+ weather_overlay = "lava"
+
+ end_message = "The ground cools and returns to its usual form."
+ end_duration = 0
+
+ area_type = /area
+ target_z = ZLEVEL_STATION
+
+ overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only
+ immunity_type = "lava"
+
+/datum/weather/floor_is_lava/impact(mob/living/L)
+ for(var/obj/structure/O in L.loc)
+ if(O.density)
+ return
+ if(L.loc.density)
+ return
+ if(!L.client) //Only sentient people are going along with it!
+ return
+ L.adjustFireLoss(3)
+
+
+/datum/weather/advanced_darkness //Advanced Darkness: Restricts the vision of all affected mobs to a single tile in the cardinal directions.
+ name = "advanced darkness"
+ desc = "Everything in the area is effectively blinded, unable to see more than a foot or so around itself."
+
+ telegraph_message = "The lights begin to dim... is the power going out?"
+ telegraph_duration = 150
+
+ weather_message = "This isn't your everday darkness... this is advanced darkness!"
+ weather_duration_lower = 300
+ weather_duration_upper = 300
+
+ end_message = "At last, the darkness recedes."
+ end_duration = 0
+
+ area_type = /area
+ target_z = ZLEVEL_STATION
+
+/datum/weather/advanced_darkness/update_areas()
+ for(var/V in impacted_areas)
+ var/area/A = V
+ if(stage == MAIN_STAGE)
+ A.invisibility = 0
+ A.opacity = 1
+ A.layer = overlay_layer
+ A.icon = 'icons/effects/weather_effects.dmi'
+ A.icon_state = "darkness"
+ else
+ A.invisibility = INVISIBILITY_MAXIMUM
+ A.opacity = 0
+
+
+/datum/weather/ash_storm //Ash Storms: Common happenings on lavaland. Heavily obscures vision and deals heavy fire damage to anyone caught outside.
+ name = "ash storm"
+ desc = "An intense atmospheric storm lifts ash off of the planet's surface and billows it down across the area, dealing intense fire damage to the unprotected."
+
+ telegraph_message = "An eerie moan rises on the wind. Sheets of burning ash blacken the horizon. Seek shelter."
+ telegraph_duration = 300
+ telegraph_sound = 'sound/lavaland/ash_storm_windup.ogg'
+ telegraph_overlay = "light_ash"
+
+ weather_message = "Smoldering clouds of scorching ash billow down around you! Get inside!"
+ weather_duration_lower = 600
+ weather_duration_upper = 1500
+ weather_sound = 'sound/lavaland/ash_storm_start.ogg'
+ weather_overlay = "ash_storm"
+
+ end_message = "The shrieking wind whips away the last of the ash falls to its usual murmur. It should be safe to go outside now."
+ end_duration = 300
+ end_sound = 'sound/lavaland/ash_storm_end.ogg'
+ end_overlay = "light_ash"
+
+ area_type = /area/lavaland/surface/outdoors
+ target_z = ZLEVEL_LAVALAND
+
+ immunity_type = "ash"
+
+ probability = 90
+
+/datum/weather/ash_storm/impact(mob/living/L)
+ if(istype(L.loc, /obj/mecha))
+ return
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ var/thermal_protection = H.get_thermal_protection()
+ if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
+ return
+ L.adjustFireLoss(4)
+
+/datum/weather/ash_storm/emberfall //Emberfall: An ash storm passes by, resulting in harmless embers falling like snow. 10% to happen in place of an ash storm.
+ name = "emberfall"
+ desc = "A passing ash storm blankets the area in harmless embers."
+
+ weather_message = "Gentle embers waft down around you like grotesque snow. The storm seems to have passed you by..."
+
+ end_message = "The emberfall slows, stops. Another layer of hardened soot to the basalt beneath your feet."
+
+ aesthetic = TRUE
+
+ probability = 10
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 26a284fa0c1..cce111cdbfb 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -427,8 +427,7 @@
L.fix()
if("floorlava")
- var/datum/weather/floor_is_lava/storm = new /datum/weather/floor_is_lava
- storm.weather_start_up()
+ SSweather.run_weather("the floor is lava")
if("virus")
if(!check_rights(R_FUN))
diff --git a/code/modules/events/wizard/advanced_darkness.dm b/code/modules/events/wizard/advanced_darkness.dm
index 62603dd9a8a..16e8042fb0a 100644
--- a/code/modules/events/wizard/advanced_darkness.dm
+++ b/code/modules/events/wizard/advanced_darkness.dm
@@ -13,5 +13,4 @@
/datum/round_event/wizard/darkness/start()
if(!started)
started = TRUE
- var/datum/weather/advanced_darkness/darkness = new
- darkness.weather_start_up()
+ SSweather.run_weather("advanced darkness")
diff --git a/code/modules/events/wizard/lava.dm b/code/modules/events/wizard/lava.dm
index 231fab230d3..80d144688a4 100644
--- a/code/modules/events/wizard/lava.dm
+++ b/code/modules/events/wizard/lava.dm
@@ -12,5 +12,4 @@
/datum/round_event/wizard/lava/start()
if(!started)
started = TRUE
- var/datum/weather/floor_is_lava/LAVA = new /datum/weather/floor_is_lava
- LAVA.weather_start_up()
+ SSweather.run_weather("the floor is lava")
diff --git a/code/modules/mining/lavaland/weather.dm b/code/modules/mining/lavaland/weather.dm
deleted file mode 100644
index 33eb1e4e6b7..00000000000
--- a/code/modules/mining/lavaland/weather.dm
+++ /dev/null
@@ -1,110 +0,0 @@
-#define STARTUP_STAGE 1
-#define MAIN_STAGE 2
-#define WIND_DOWN_STAGE 3
-#define END_STAGE 4
-
-/datum/weather
- var/name = "storm"
- var/start_up_time = 300 //30 seconds
- var/start_up_message = "The wind begins to pick up."
- var/start_up_sound
- var/duration = 120 //2 minutes
- var/duration_lower = 120
- var/duration_upper = 120
- var/duration_sound
- var/duration_message = "A storm has started!"
- var/wind_down = 300 // 30 seconds
- var/wind_down_message = "The storm is passing."
- var/wind_down_sound
-
- var/target_z = 1
- var/exclude_walls = TRUE
- var/area_type = /area/space
- var/stage = STARTUP_STAGE
-
-
- var/start_up_overlay = "lava"
- var/duration_overlay = "lava"
- var/overlay_layer = AREA_LAYER //This is the default area layer, and above everything else. TURF_LAYER is floors/below walls and mobs.
- var/purely_aesthetic = FALSE //If we just want gentle rain that doesn't hurt people
- var/list/impacted_areas = list()
- var/immunity_type = "storm"
-
-/datum/weather/proc/weather_start_up()
- for(var/area/N in get_areas(area_type))
- if(N.z == target_z)
- impacted_areas += N
- duration = rand(duration_lower,duration_upper)
- update_areas()
- for(var/mob/M in player_list)
- if(M.z == target_z)
- M << "[start_up_message]"
- if(start_up_sound)
- M << start_up_sound
- sleep(start_up_time)
- if(src && stage != MAIN_STAGE)
- stage = MAIN_STAGE
- weather_main()
-
-
-/datum/weather/proc/weather_main()
- update_areas()
- for(var/mob/M in player_list)
- if(M.z == target_z)
- M << "[duration_message]"
- if(duration_sound)
- M << duration_sound
- if(purely_aesthetic)
- sleep(duration*10)
- else //Storm effects
- for(var/i in 1 to duration-1)
- for(var/mob/living/L in living_mob_list)
- var/area/storm_area = get_area(L)
- if(storm_area in impacted_areas)
- storm_act(L)
- sleep(10)
-
- if(src && stage != WIND_DOWN_STAGE)
- stage = WIND_DOWN_STAGE
- weather_wind_down()
-
-
-/datum/weather/proc/weather_wind_down()
- update_areas()
- for(var/mob/M in player_list)
- if(M.z == target_z)
- M << "[wind_down_message]"
- if(wind_down_sound)
- M << wind_down_sound
- sleep(wind_down)
-
- if(src && stage != END_STAGE)
- stage = END_STAGE
- update_areas()
-
-
-/datum/weather/proc/storm_act(mob/living/L)
- if(immunity_type in L.weather_immunities)
- return
-
-/datum/weather/proc/update_areas()
- for(var/area/N in impacted_areas)
- N.layer = overlay_layer
- N.icon = 'icons/effects/weather_effects.dmi'
- N.invisibility = 0
- switch(stage)
- if(STARTUP_STAGE)
- N.icon_state = start_up_overlay
-
- if(MAIN_STAGE)
- N.icon_state = duration_overlay
-
- if(WIND_DOWN_STAGE)
- N.icon_state = start_up_overlay
-
- if(END_STAGE)
- N.icon_state = initial(N.icon_state)
- N.icon = 'icons/turf/areas.dmi'
- N.layer = AREA_LAYER //Just default back to normal area stuff since I assume setting a var is faster than initial
- N.invisibility = INVISIBILITY_MAXIMUM
- N.opacity = 0
\ No newline at end of file
diff --git a/code/modules/mining/lavaland/weather_types.dm b/code/modules/mining/lavaland/weather_types.dm
deleted file mode 100644
index bc205602ccc..00000000000
--- a/code/modules/mining/lavaland/weather_types.dm
+++ /dev/null
@@ -1,108 +0,0 @@
-///The floor is lava
-
-/datum/weather/floor_is_lava
- name = "floor is lava"
- start_up_time = 30 //3 seconds
- start_up_message = "The ground begins to bubble."
- duration_lower = 45
- duration_upper = 60 //1 minute
- duration_message = "The floor is lava!"
- wind_down = 30// 3 seconds
- wind_down_message = "The ground begins to cool."
-
- target_z = 1
- exclude_walls = TRUE
- area_type = /area
-
- start_up_overlay = "lava"
- duration_overlay = "lava"
- overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only
-
- immunity_type = "lava"
-
-
-/datum/weather/floor_is_lava/storm_act(mob/living/L)
- if(immunity_type in L.weather_immunities)
- return
-
- var/turf/F = get_turf(L)
- for(var/obj/structure/O in F.contents)
- if(O.level > F.level && !istype(O, /obj/structure/window)) // Something to stand on and it isn't under the floor!
- return
- L.adjustFireLoss(3)
-
-
-
-/datum/weather/advanced_darkness
- name = "advanced darkness"
- start_up_time = 100 //10 seconds
- start_up_message = "The lights begin to dim... is power going out?"
- duration_lower = 45
- duration_upper = 60 //1 minute
- duration_message = "This isn't average everyday darkness... this is advanced darkness!"
- wind_down = 100 // 10 seconds
- wind_down_message = "The darkness recedes."
- purely_aesthetic = TRUE
-
- target_z = 1
- exclude_walls = TRUE
- area_type = /area
-
- start_up_overlay = ""
- duration_overlay = ""
- overlay_layer = AREA_LAYER
-
-/datum/weather/advanced_darkness/update_areas()
- for(var/area/A in impacted_areas)
- if(stage == MAIN_STAGE)
- A.invisibility = 0
- A.opacity = 1
- A.layer = overlay_layer
- A.icon = 'icons/effects/weather_effects.dmi'
- A.icon_state = start_up_overlay
- else
- A.invisibility = INVISIBILITY_MAXIMUM
- A.opacity = 0
-//Ash storms
-
-/datum/weather/ash_storm
- name = "ash storm"
- start_up_time = 300 //30 seconds
- start_up_message = "An eerie moan rises on the wind. Sheets of burning ash blacken the horizon. Seek shelter."
- start_up_sound = 'sound/lavaland/ash_storm_windup.ogg'
- duration_lower = 60 //1 minute
- duration_upper = 150 //2.5 minutes
- duration_message = "Smoldering clouds of scorching ash billow down around you! Get inside!"
- duration_sound = 'sound/lavaland/ash_storm_start.ogg'
- wind_down = 300 // 30 seconds
- wind_down_message = "The shrieking wind whips away the last of the ash and falls to its usual murmur. It should be safe to go outside now."
- wind_down_sound = 'sound/lavaland/ash_storm_end.ogg'
-
- target_z = ZLEVEL_LAVALAND
- area_type = /area/lavaland/surface/outdoors
-
- start_up_overlay = "light_ash"
- duration_overlay = "ash_storm"
- overlay_layer = AREA_LAYER
-
- immunity_type = "ash"
-
-
-/datum/weather/ash_storm/false_alarm //No storm, just light ember fall
- purely_aesthetic = TRUE
- duration_overlay = "light_ash"
- duration_message = "Gentle ashfall surrounds you like grotesque snow. The storm seems to have passed you by."
- wind_down_message = "The ashfall quietly slows, then stops. Another layer of hardened soot to the volcanic rock beneath you."
-
-/datum/weather/ash_storm/storm_act(mob/living/L)
- if(immunity_type in L.weather_immunities)
- return
-
- if(istype(L.loc, /obj/mecha))
- return
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- var/thermal_protection = H.get_thermal_protection()
- if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
- return
- L.adjustFireLoss(4)
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
index c4ae6eefecf..2820dd3ff77 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/legion.dm
@@ -118,37 +118,38 @@
force = 25
damtype = BURN
hitsound = 'sound/weapons/sear.ogg'
- var/obj/machinery/lavaland_controller/linked_machine
var/storm_cooldown = 0
/obj/item/weapon/staff_of_storms/attack_self(mob/user)
if(storm_cooldown > world.time)
user << "The staff is still recharging!"
return
+ if(user.z != ZLEVEL_LAVALAND)
+ user << "You can't seem to control the weather here!"
+ return
- if(!linked_machine || linked_machine.z != user.z)
- for(var/obj/machinery/lavaland_controller/controller in machines)
- if(controller.z == user.z)
- linked_machine = controller
- break
+ var/datum/weather/ash_storm/A
+ for(var/V in SSweather.existing_weather)
+ var/datum/weather/W = V
+ if(W.name == "ash storm")
+ A = W
+ break
+ if(!A)
+ user << "How odd! The planet seems to have lost its atmosphere!"
+ return
- if(linked_machine && linked_machine.ongoing_weather)
- if(linked_machine.ongoing_weather.stage == WIND_DOWN_STAGE || linked_machine.ongoing_weather.stage == END_STAGE)
- user << "The storm is already ending. It would be a waste to use the staff now."
+ if(A.stage != END_STAGE)
+ if(A.stage == WIND_DOWN_STAGE)
+ user << "The storm is already ending! It would be a waste to use the staff now."
return
- user.visible_message("[user] holds [src] skywards, causing its orb to flare!", \
- "With an appropriately dramatic flourish, you dispel the storm!")
- playsound(get_turf(src),'sound/magic/Staff_Change.ogg', 200, 0)
- storm_cooldown = world.time + 600
- linked_machine.ongoing_weather.stage = WIND_DOWN_STAGE
- linked_machine.ongoing_weather.weather_wind_down()
-
- else if (linked_machine && !linked_machine.ongoing_weather)
- user.visible_message("[user] holds [src] skywards, causing its orb to flare!", \
- "You lift your staff skywards, calling down a terrible storm!")
- playsound(get_turf(src),'sound/magic/Staff_Chaos.ogg', 200, 0)
- storm_cooldown = world.time + 600
- linked_machine.weather_cooldown = 0
-
+ user.visible_message("[user] holds [src] skywards as an orange beam travels into the sky!", \
+ "You hold [src] skyward, dispelling the ash storm!")
+ playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0)
+ A.wind_down()
else
- user << "You can't seem to control the weather here."
+ user.visible_message("[user] holds [src] skywards as red lightning crackles into the sky!", \
+ "You hold [src] skyward, calling down a terrible storm!")
+ playsound(user, 'sound/magic/Staff_Chaos.ogg', 200, 0)
+ A.telegraph()
+
+ storm_cooldown = world.time + 600
diff --git a/code/modules/ruins/lavaland_ruin_code.dm b/code/modules/ruins/lavaland_ruin_code.dm
index ac45476b535..030bafcf6ce 100644
--- a/code/modules/ruins/lavaland_ruin_code.dm
+++ b/code/modules/ruins/lavaland_ruin_code.dm
@@ -1,32 +1,10 @@
//If you're looking for spawners like ash walker eggs, check ghost_role_spawners.dm
/obj/machinery/lavaland_controller
- name = "weather control machine"
- desc = "Controls the weather."
+ name = "weather machine"
+ desc = "Controls the weather... when it's on, at any rate. A sticky note on the side proclaims \"DISABLED IN FAVOR OF AN ACTUAL ATMOSPHERE\"."
icon = 'icons/obj/machines/telecomms.dmi'
- icon_state = "processor"
- var/datum/weather/ongoing_weather = FALSE
- var/weather_cooldown = 0
-
-/obj/machinery/lavaland_controller/process()
- if(ongoing_weather || weather_cooldown > world.time)
- return
- weather_cooldown = world.time + rand(3500, 6500)
- var/datum/weather/ash_storm/LAVA
- if(prob(10)) //10% chance for the ash storm to miss the area entirely
- LAVA = new /datum/weather/ash_storm/false_alarm
- else
- LAVA = new /datum/weather/ash_storm
- ongoing_weather = LAVA
- LAVA.weather_start_up()
- ongoing_weather = null
-
-/obj/machinery/lavaland_controller/Destroy(force)
- if(force)
- . = ..()
- else
- return QDEL_HINT_LETMELIVE
-
+ icon_state = "processor_off"
/obj/structure/fans/tiny/invisible //For blocking air in ruin doorways
invisibility = INVISIBILITY_ABSTRACT
diff --git a/tgstation.dme b/tgstation.dme
index f3eb84d2735..80be1fa2d4e 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -156,6 +156,7 @@
#include "code\controllers\subsystem\ticker.dm"
#include "code\controllers\subsystem\timer.dm"
#include "code\controllers\subsystem\voting.dm"
+#include "code\controllers\subsystem\weather.dm"
#include "code\datums\action.dm"
#include "code\datums\ai_laws.dm"
#include "code\datums\beam.dm"
@@ -238,6 +239,8 @@
#include "code\datums\martial\wrestling.dm"
#include "code\datums\ruins\lavaland.dm"
#include "code\datums\ruins\space.dm"
+#include "code\datums\weather\weather.dm"
+#include "code\datums\weather\weather_types.dm"
#include "code\datums\wires\airalarm.dm"
#include "code\datums\wires\airlock.dm"
#include "code\datums\wires\apc.dm"
@@ -1254,8 +1257,6 @@
#include "code\modules\mining\laborcamp\laborstacker.dm"
#include "code\modules\mining\lavaland\lavaland_areas.dm"
#include "code\modules\mining\lavaland\necropolis_chests.dm"
-#include "code\modules\mining\lavaland\weather.dm"
-#include "code\modules\mining\lavaland\weather_types.dm"
#include "code\modules\mining\lavaland\ruins\gym.dm"
#include "code\modules\mob\death.dm"
#include "code\modules\mob\interactive.dm"