//The effects of weather occur across an entire z-level. For instance, lavaland has periodic ash storms that scorch most unprotected creatures. /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/weather_color = null var/end_message = "The wind relents its assault." //Displayed once the weather 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/list/protected_areas = list()//Areas that are protected and excluded from the affected areas. var/impacted_z_levels // The list of z-levels that this weather is actively affecting 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 // These are read by the weather subsystem and used to determine when and where to run the weather. var/probability = 0 // Weight amongst other eligible weather. If zero, will never happen randomly. var/target_trait = ZTRAIT_STATION // The z-level trait to affect when run randomly or when not overridden. var/barometer_predictable = FALSE var/next_hit_time = 0 //For barometers to know when the next storm will hit /datum/weather/New(z_levels) ..() impacted_z_levels = z_levels /datum/weather/proc/telegraph() if(stage == STARTUP_STAGE) return stage = STARTUP_STAGE var/list/affectareas = list() for(var/V in get_areas(area_type)) var/area/A = V affectareas |= A if(A.sub_areas) affectareas |= A.sub_areas for(var/V in protected_areas) affectareas -= get_areas(V) for(var/V in affectareas) var/area/A = V if(A.z in impacted_z_levels) impacted_areas |= A weather_duration = rand(weather_duration_lower, weather_duration_upper) START_PROCESSING(SSweather, src) //The reason this doesn't start and stop at main stage is because processing list is also used to see active running weathers (for example, you wouldn't want two ash storms starting at once.) update_areas() for(var/M in GLOB.player_list) var/turf/mob_turf = get_turf(M) if(mob_turf && (mob_turf.z in impacted_z_levels)) if(telegraph_message) to_chat(M, telegraph_message) if(telegraph_sound) SEND_SOUND(M, sound(telegraph_sound)) addtimer(CALLBACK(src, .proc/start), telegraph_duration) /datum/weather/proc/start() if(stage >= MAIN_STAGE) return stage = MAIN_STAGE update_areas() for(var/M in GLOB.player_list) var/turf/mob_turf = get_turf(M) if(mob_turf && (mob_turf.z in impacted_z_levels)) if(weather_message) to_chat(M, weather_message) if(weather_sound) SEND_SOUND(M, sound(weather_sound)) addtimer(CALLBACK(src, .proc/wind_down), weather_duration) /datum/weather/proc/wind_down() if(stage >= WIND_DOWN_STAGE) return stage = WIND_DOWN_STAGE update_areas() for(var/M in GLOB.player_list) var/turf/mob_turf = get_turf(M) if(mob_turf && (mob_turf.z in impacted_z_levels)) if(end_message) to_chat(M, end_message) if(end_sound) SEND_SOUND(M, sound(end_sound)) addtimer(CALLBACK(src, .proc/end), end_duration) /datum/weather/proc/end() if(stage == END_STAGE) return 1 stage = END_STAGE STOP_PROCESSING(SSweather, src) update_areas() /datum/weather/process() if(aesthetic || (stage != MAIN_STAGE)) return for(var/i in GLOB.mob_living_list) var/mob/living/L = i if(can_weather_act(L)) weather_act(L) /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 in impacted_z_levels)) return if(immunity_type in L.weather_immunities) return if(!(get_area(L) in impacted_areas)) return return 1 /datum/weather/proc/weather_act(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.color = weather_color 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.color = null 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.set_opacity(FALSE)