mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-19 12:05:59 +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:
@@ -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
|
||||
@@ -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 = "<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/end_message = "<span class='danger'>The wind relents its assault.</span>" //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
|
||||
@@ -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 = "<span class='warning'>Waves of heat emanate from the ground...</span>"
|
||||
telegraph_duration = 150
|
||||
|
||||
weather_message = "<span class='userdanger'>The floor is lava! Get on top of something!</span>"
|
||||
weather_duration_lower = 300
|
||||
weather_duration_upper = 600
|
||||
weather_overlay = "lava"
|
||||
|
||||
end_message = "<span class='danger'>The ground cools and returns to its usual form.</span>"
|
||||
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 = "<span class='warning'>The lights begin to dim... is the power going out?</span>"
|
||||
telegraph_duration = 150
|
||||
|
||||
weather_message = "<span class='userdanger'>This isn't your everday darkness... this is <i>advanced</i> darkness!</span>"
|
||||
weather_duration_lower = 300
|
||||
weather_duration_upper = 300
|
||||
|
||||
end_message = "<span class='danger'>At last, the darkness recedes.</span>"
|
||||
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 = "<span class='boldwarning'>An eerie moan rises on the wind. Sheets of burning ash blacken the horizon. Seek shelter.</span>"
|
||||
telegraph_duration = 300
|
||||
telegraph_sound = 'sound/lavaland/ash_storm_windup.ogg'
|
||||
telegraph_overlay = "light_ash"
|
||||
|
||||
weather_message = "<span class='userdanger'><i>Smoldering clouds of scorching ash billow down around you! Get inside!</i></span>"
|
||||
weather_duration_lower = 600
|
||||
weather_duration_upper = 1500
|
||||
weather_sound = 'sound/lavaland/ash_storm_start.ogg'
|
||||
weather_overlay = "ash_storm"
|
||||
|
||||
end_message = "<span class='boldannounce'>The shrieking wind whips away the last of the ash falls to its usual murmur. It should be safe to go outside now.</span>"
|
||||
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 = "<span class='notice'>Gentle embers waft down around you like grotesque snow. The storm seems to have passed you by...</span>"
|
||||
|
||||
end_message = "<span class='notice'>The emberfall slows, stops. Another layer of hardened soot to the basalt beneath your feet.</span>"
|
||||
|
||||
aesthetic = TRUE
|
||||
|
||||
probability = 10
|
||||
@@ -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))
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
@@ -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 << "<span class='warning'>The staff is still recharging!</span>"
|
||||
return
|
||||
if(user.z != ZLEVEL_LAVALAND)
|
||||
user << "<span class='warning'>You can't seem to control the weather here!</span>"
|
||||
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 << "<span class='warning'>How odd! The planet seems to have lost its atmosphere!</span>"
|
||||
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 << "<span class='warning'>The storm is already ending. It would be a waste to use the staff now.</span>"
|
||||
if(A.stage != END_STAGE)
|
||||
if(A.stage == WIND_DOWN_STAGE)
|
||||
user << "<span class='warning'>The storm is already ending! It would be a waste to use the staff now.</span>"
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] holds [src] skywards, causing its orb to flare!</span>", \
|
||||
"<span class='notice'>With an appropriately dramatic flourish, you dispel the storm!</span>")
|
||||
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("<span class='warning'>[user] holds [src] skywards, causing its orb to flare!</span>", \
|
||||
"<span class='danger'>You lift your staff skywards, calling down a terrible storm!</span>")
|
||||
playsound(get_turf(src),'sound/magic/Staff_Chaos.ogg', 200, 0)
|
||||
storm_cooldown = world.time + 600
|
||||
linked_machine.weather_cooldown = 0
|
||||
|
||||
user.visible_message("<span class='warning'>[user] holds [src] skywards as an orange beam travels into the sky!</span>", \
|
||||
"<span class='notice'>You hold [src] skyward, dispelling the ash storm!</span>")
|
||||
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("<span class='warning'>[user] holds [src] skywards as red lightning crackles into the sky!</span>", \
|
||||
"<span class='notice'>You hold [src] skyward, calling down a terrible storm!</span>")
|
||||
playsound(user, 'sound/magic/Staff_Chaos.ogg', 200, 0)
|
||||
A.telegraph()
|
||||
|
||||
storm_cooldown = world.time + 600
|
||||
|
||||
@@ -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
|
||||
|
||||
+3
-2
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user