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"