mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-13 00:55:20 +01:00
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:
@@ -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 << "<span class='warning'><B>[start_up_message]</B></span>"
|
||||
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 << "<span class='userdanger'><i>[duration_message]</i></span>"
|
||||
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 << "<span class='danger'><B>[wind_down_message]</B></span>"
|
||||
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
|
||||
@@ -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 = "<span class='notice'>Gentle ashfall surrounds you like grotesque snow. The storm seems to have passed you by.</span>"
|
||||
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)
|
||||
Reference in New Issue
Block a user