150 lines
5.7 KiB
Plaintext
150 lines
5.7 KiB
Plaintext
//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 = "<span class='warning'>The wind begins to pick up.</span>" //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 = "<span class='userdanger'>The wind begins to blow ferociously!</span>" //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 = "<span class='danger'>The wind relents its assault.</span>" //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)
|