diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm
index 88102e260c..e66fd4ffeb 100644
--- a/code/controllers/subsystem/weather.dm
+++ b/code/controllers/subsystem/weather.dm
@@ -14,8 +14,8 @@ SUBSYSTEM_DEF(weather)
if(W.aesthetic)
continue
for(var/mob/living/L in GLOB.mob_list)
- if(W.can_impact(L))
- W.impact(L)
+ if(W.can_weather_act(L))
+ W.weather_act(L)
for(var/Z in eligible_zlevels)
var/list/possible_weather_for_this_z = list()
for(var/V in existing_weather)
@@ -30,8 +30,7 @@ SUBSYSTEM_DEF(weather)
/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
+ new V //Weather's New() will handle adding stuff to the list
/datum/controller/subsystem/weather/proc/run_weather(weather_name, Z)
if(!weather_name)
diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm
index a2abdf64a1..e3e7e83dcf 100644
--- a/code/datums/weather/weather.dm
+++ b/code/datums/weather/weather.dm
@@ -42,7 +42,7 @@
/datum/weather/New()
..()
- SSweather.existing_weather |= src
+ SSweather.existing_weather += src
/datum/weather/Destroy()
SSweather.existing_weather -= src
@@ -108,7 +108,7 @@
stage = END_STAGE
update_areas()
-/datum/weather/proc/can_impact(mob/living/L) //Can this weather impact a mob?
+/datum/weather/proc/can_weather_act(mob/living/L) //Can this weather impact a mob?
var/turf/mob_turf = get_turf(L)
if(mob_turf && (mob_turf.z != target_z))
return
@@ -118,7 +118,7 @@
return
return 1
-/datum/weather/proc/impact(mob/living/L) //What effect does this weather have on the hapless mob?
+/datum/weather/proc/weather_act(mob/living/L) //What effect does this weather have on the hapless mob?
return
/datum/weather/proc/update_areas()
diff --git a/code/datums/weather/weather_types.dm b/code/datums/weather/weather_types.dm
deleted file mode 100644
index 3368dcf1dd..0000000000
--- a/code/datums/weather/weather_types.dm
+++ /dev/null
@@ -1,225 +0,0 @@
-//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
- protected_areas = list(/area/space)
- target_z = ZLEVEL_STATION_PRIMARY
-
- 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 average 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_PRIMARY
-
-/datum/weather/advanced_darkness/update_areas()
- for(var/V in impacted_areas)
- var/area/A = V
- if(stage == MAIN_STAGE)
- A.invisibility = 0
- A.set_opacity(TRUE)
- A.layer = overlay_layer
- A.icon = 'icons/effects/weather_effects.dmi'
- A.icon_state = "darkness"
- else
- A.invisibility = INVISIBILITY_MAXIMUM
- A.set_opacity(FALSE)
-
-
-/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 and 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/proc/is_ash_immune(mob/living/L)
- if(istype(L.loc, /obj/mecha)) //Mechs are immune
- return TRUE
- if(ishuman(L)) //Are you immune?
- var/mob/living/carbon/human/H = L
- var/thermal_protection = H.get_thermal_protection()
- if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
- return TRUE
- if(istype(L.loc, /mob/living) && L.loc != L) //Matryoshka check
- return is_ash_immune(L.loc)
- return FALSE //RIP you
-
-/datum/weather/ash_storm/impact(mob/living/L)
- if(is_ash_immune(L))
- 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..."
- weather_sound = 'sound/lavaland/ash_storm_windup.ogg'
- weather_overlay = "light_ash"
-
- end_message = "The emberfall slows, stops. Another layer of hardened soot to the basalt beneath your feet."
-
- aesthetic = TRUE
-
- probability = 10
-
-/datum/weather/rad_storm
- name = "radiation storm"
- desc = "A cloud of intense radiation passes through the area dealing rad damage to those who are unprotected."
-
- telegraph_duration = 400
- telegraph_message = "The air begins to grow warm."
-
- weather_message = "You feel waves of heat wash over you! Find shelter!"
- weather_overlay = "ash_storm"
- weather_duration_lower = 100
- weather_duration_upper = 600
- weather_color = "green"
- weather_sound = 'sound/misc/bloblarm.ogg'
-
- end_duration = 100
- end_message = "The air seems to be cooling off again."
-
- area_type = /area
- protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
- /area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle)
- target_z = ZLEVEL_STATION_PRIMARY
-
- immunity_type = "rad"
-
-/datum/weather/rad_storm/telegraph()
- ..()
- status_alarm("alert")
-
-
-/datum/weather/rad_storm/impact(mob/living/L)
- var/resist = L.getarmor(null, "rad")
- if(prob(40))
- if(ishuman(L))
- var/mob/living/carbon/human/H = L
- if(H.dna && H.dna.species)
- if(!(RADIMMUNE in H.dna.species.species_traits))
- if(prob(max(0,100-resist)))
- H.randmuti()
- if(prob(50))
- if(prob(90))
- H.randmutb()
- else
- H.randmutg()
- H.domutcheck()
- L.rad_act(20,1)
-/datum/weather/rad_storm/end()
- if(..())
- return
- priority_announce("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert")
- status_alarm()
- sleep(300)
- revoke_maint_all_access() // Need to make this a timer at some point.
-
-
-/datum/weather/rad_storm/proc/status_alarm(command) //Makes the status displays show the radiation warning for those who missed the announcement.
- var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
-
- if(!frequency)
- return
-
- var/datum/signal/status_signal = new
- var/atom/movable/virtualspeaker/virt = new /atom/movable/virtualspeaker(null)
- status_signal.source = virt
- status_signal.transmission_method = 1
- status_signal.data["command"] = "shuttle"
-
- if(command == "alert")
- status_signal.data["command"] = "alert"
- status_signal.data["picture_state"] = "radiation"
-
- frequency.post_signal(src, status_signal)
-
-
-/datum/weather/acid_rain
- name = "acid rain"
- desc = "Some stay dry and others feel the pain"
-
- telegraph_duration = 400
- telegraph_message = "Stinging droplets start to fall upon you.."
- telegraph_sound = 'sound/ambience/acidrain_start.ogg'
-
- weather_message = "Your skin melts underneath the rain!"
- weather_overlay = "acid_rain"
- weather_duration_lower = 600
- weather_duration_upper = 1500
- weather_sound = 'sound/ambience/acidrain_mid.ogg'
-
- end_duration = 100
- end_message = "The rain starts to dissipate."
- end_sound = 'sound/ambience/acidrain_end.ogg'
-
- area_type = /area/lavaland/surface/outdoors
- target_z = ZLEVEL_LAVALAND
-
- immunity_type = "acid" // temp
-
-
-/datum/weather/acid_rain/impact(mob/living/L)
- var/resist = L.getarmor(null, "acid")
- if(prob(max(0,100-resist)))
- L.acid_act(20,20)
diff --git a/code/datums/weather/weather_types/acid_rain.dm b/code/datums/weather/weather_types/acid_rain.dm
new file mode 100644
index 0000000000..cb4ced8595
--- /dev/null
+++ b/code/datums/weather/weather_types/acid_rain.dm
@@ -0,0 +1,29 @@
+//Acid rain is part of the natural weather cycle in the humid forests of Planetstation, and cause acid damage to anyone unprotected.
+/datum/weather/acid_rain
+ name = "acid rain"
+ desc = "The planet's thunderstorms are by nature acidic, and will incinerate anyone standing beneath them without protection."
+
+ telegraph_duration = 400
+ telegraph_message = "Thunder rumbles far above. You hear droplets drumming against the canopy. Seek shelter."
+ telegraph_sound = 'sound/ambience/acidrain_start.ogg'
+
+ weather_message = "Acidic rain pours down around you! Get inside!"
+ weather_overlay = "acid_rain"
+ weather_duration_lower = 600
+ weather_duration_upper = 1500
+ weather_sound = 'sound/ambience/acidrain_mid.ogg'
+
+ end_duration = 100
+ end_message = "The downpour gradually slows to a light shower. It should be safe outside now."
+ end_sound = 'sound/ambience/acidrain_end.ogg'
+
+ area_type = /area/lavaland/surface/outdoors
+ target_z = ZLEVEL_LAVALAND
+
+ immunity_type = "acid" // temp
+
+
+/datum/weather/acid_rain/weather_act(mob/living/L)
+ var/resist = L.getarmor(null, "acid")
+ if(prob(max(0,100-resist)))
+ L.acid_act(20,20)
diff --git a/code/datums/weather/weather_types/advanced_darkness.dm b/code/datums/weather/weather_types/advanced_darkness.dm
new file mode 100644
index 0000000000..75cc2b1a5f
--- /dev/null
+++ b/code/datums/weather/weather_types/advanced_darkness.dm
@@ -0,0 +1,30 @@
+//Restricts the vision of affected mobs to a single tile in the cardinal directions.
+/datum/weather/advanced_darkness
+ name = "advanced darkness"
+ desc = "Everything in the area is effectively blinded, unable to see more than a foot or so around itself."
+
+ telegraph_message = "Your eyes hurt... a vignette settles in your vision and closes in."
+ telegraph_duration = 150
+
+ weather_message = "This isn't your average 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_PRIMARY
+
+/datum/weather/advanced_darkness/update_areas()
+ for(var/V in impacted_areas)
+ var/area/A = V
+ if(stage == MAIN_STAGE)
+ A.invisibility = 0
+ A.set_opacity(TRUE)
+ A.layer = overlay_layer
+ A.icon = 'icons/effects/weather_effects.dmi'
+ A.icon_state = "darkness"
+ else
+ A.invisibility = INVISIBILITY_MAXIMUM
+ A.set_opacity(FALSE)
diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm
new file mode 100644
index 0000000000..2c2212fde5
--- /dev/null
+++ b/code/datums/weather/weather_types/ash_storm.dm
@@ -0,0 +1,61 @@
+//Ash storms happen frequently on lavaland. They heavily obscure vision, and cause high fire damage to anyone caught outside.
+/datum/weather/ash_storm
+ 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 = 1200
+ weather_sound = 'sound/lavaland/ash_storm_start.ogg'
+ weather_overlay = "ash_storm"
+
+ end_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."
+ 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/proc/is_ash_immune(mob/living/L)
+ if(istype(L.loc, /obj/mecha)) //Mechs are immune
+ return TRUE
+ if(ishuman(L)) //Are you immune?
+ var/mob/living/carbon/human/H = L
+ var/thermal_protection = H.get_thermal_protection()
+ if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
+ return TRUE
+ if(istype(L.loc, /mob/living) && L.loc != L) //Matryoshka check
+ return is_ash_immune(L.loc)
+ return FALSE //RIP you
+
+/datum/weather/ash_storm/weather_act(mob/living/L)
+ if(is_ash_immune(L))
+ return
+ L.adjustFireLoss(4)
+
+
+//Emberfalls are the result of an ash storm passing by close to the playable area of lavaland. They have a 10% chance to trigger in place of an ash storm.
+/datum/weather/ash_storm/emberfall
+ 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..."
+ weather_sound = 'sound/lavaland/ash_storm_windup.ogg'
+ weather_overlay = "light_ash"
+
+ end_message = "The emberfall slows, stops. Another layer of hardened soot to the basalt beneath your feet."
+ end_sound = null
+
+ aesthetic = TRUE
+
+ probability = 10
diff --git a/code/datums/weather/weather_types/floor_is_lava.dm b/code/datums/weather/weather_types/floor_is_lava.dm
new file mode 100644
index 0000000000..52f82abec9
--- /dev/null
+++ b/code/datums/weather/weather_types/floor_is_lava.dm
@@ -0,0 +1,32 @@
+//Causes fire damage to anyone not standing on a dense object.
+/datum/weather/floor_is_lava
+ name = "the floor is lava"
+ desc = "The ground turns into surprisingly cool lava, lightly damaging anything on the floor."
+
+ telegraph_message = "You feel the ground beneath you getting hot. Waves of heat distort the air."
+ 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
+ protected_areas = list(/area/space)
+ target_z = ZLEVEL_STATION_PRIMARY
+
+ overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only
+ immunity_type = "lava"
+
+/datum/weather/floor_is_lava/weather_act(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)
diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm
new file mode 100644
index 0000000000..3c11750dda
--- /dev/null
+++ b/code/datums/weather/weather_types/radiation_storm.dm
@@ -0,0 +1,72 @@
+//Radiation storms occur when the station passes through an irradiated area, and irradiate anyone not standing in protected areas (maintenance, emergency storage, etc.)
+/datum/weather/rad_storm
+ name = "radiation storm"
+ desc = "A cloud of intense radiation passes through the area dealing rad damage to those who are unprotected."
+
+ telegraph_duration = 400
+ telegraph_message = "The air begins to grow warm."
+
+ weather_message = "You feel waves of heat wash over you! Find shelter!"
+ weather_overlay = "ash_storm"
+ weather_duration_lower = 600
+ weather_duration_upper = 1500
+ weather_color = "green"
+ weather_sound = 'sound/misc/bloblarm.ogg'
+
+ end_duration = 100
+ end_message = "The air seems to be cooling off again."
+
+ area_type = /area
+ protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
+ /area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle)
+ target_z = ZLEVEL_STATION_PRIMARY
+
+ immunity_type = "rad"
+
+/datum/weather/rad_storm/telegraph()
+ ..()
+ status_alarm("alert")
+
+
+/datum/weather/rad_storm/weather_act(mob/living/L)
+ var/resist = L.getarmor(null, "rad")
+ if(prob(40))
+ if(ishuman(L))
+ var/mob/living/carbon/human/H = L
+ if(H.dna && H.dna.species)
+ if(!(RADIMMUNE in H.dna.species.species_traits))
+ if(prob(max(0,100-resist)))
+ H.randmuti()
+ if(prob(50))
+ if(prob(90))
+ H.randmutb()
+ else
+ H.randmutg()
+ H.domutcheck()
+ L.rad_act(20,1)
+
+/datum/weather/rad_storm/end()
+ if(..())
+ return
+ priority_announce("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert")
+ status_alarm()
+ sleep(300)
+ revoke_maint_all_access() // Need to make this a timer at some point.
+
+/datum/weather/rad_storm/proc/status_alarm(command) //Makes the status displays show the radiation warning for those who missed the announcement.
+ var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
+
+ if(!frequency)
+ return
+
+ var/datum/signal/status_signal = new
+ var/atom/movable/virtualspeaker/virt = new /atom/movable/virtualspeaker(null)
+ status_signal.source = virt
+ status_signal.transmission_method = 1
+ status_signal.data["command"] = "shuttle"
+
+ if(command == "alert")
+ status_signal.data["command"] = "alert"
+ status_signal.data["picture_state"] = "radiation"
+
+ frequency.post_signal(src, status_signal)
diff --git a/tgstation.dme b/tgstation.dme
index c035d52d60..67ab66c452 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -357,7 +357,11 @@
#include "code\datums\status_effects\neutral.dm"
#include "code\datums\status_effects\status_effect.dm"
#include "code\datums\weather\weather.dm"
-#include "code\datums\weather\weather_types.dm"
+#include "code\datums\weather\weather_types\acid_rain.dm"
+#include "code\datums\weather\weather_types\advanced_darkness.dm"
+#include "code\datums\weather\weather_types\ash_storm.dm"
+#include "code\datums\weather\weather_types\floor_is_lava.dm"
+#include "code\datums\weather\weather_types\radiation_storm.dm"
#include "code\datums\wires\airalarm.dm"
#include "code\datums\wires\airlock.dm"
#include "code\datums\wires\apc.dm"