mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Adds Lava/Water Idle sounds Adds Snowbirds loops for use on Sif, currently meant to be looped Adds better rain FX, gives storms their own FX too Adds unused rumbly noises for underground
558 lines
17 KiB
Plaintext
558 lines
17 KiB
Plaintext
var/datum/planet/sif/planet_sif = null
|
|
|
|
/datum/planet/sif
|
|
name = "Sif"
|
|
desc = "Sif is a terrestrial planet in the Vir system. It is somewhat earth-like, in that it has oceans, a \
|
|
breathable atmosphere, a magnetic field, weather, and similar gravity to Earth. It is currently the capital planet of Vir. \
|
|
Its center of government is the equatorial city and site of first settlement, New Reykjavik." // Ripped straight from the wiki.
|
|
current_time = new /datum/time/sif() // 32 hour clocks are nice.
|
|
// expected_z_levels = list(1) // To be changed when real map is finished.
|
|
planetary_wall_type = /turf/unsimulated/wall/planetary/sif
|
|
|
|
sun_name = "Vir"
|
|
moon_name = "Thor"
|
|
|
|
/datum/planet/sif/New()
|
|
..()
|
|
planet_sif = src
|
|
weather_holder = new /datum/weather_holder/sif(src) // Cold weather is also nice.
|
|
|
|
// This code is horrible.
|
|
/datum/planet/sif/update_sun()
|
|
..()
|
|
var/datum/time/time = current_time
|
|
var/length_of_day = time.seconds_in_day / 10 / 60 / 60 // 32
|
|
var/noon = length_of_day / 2
|
|
var/distance_from_noon = abs(text2num(time.show_time("hh")) - noon)
|
|
sun_position = distance_from_noon / noon
|
|
sun_position = abs(sun_position - 1)
|
|
|
|
var/low_brightness = null
|
|
var/high_brightness = null
|
|
|
|
var/low_color = null
|
|
var/high_color = null
|
|
var/min = 0
|
|
|
|
switch(sun_position)
|
|
if(0 to 0.40) // Night
|
|
low_brightness = 0.2
|
|
low_color = "#000066"
|
|
|
|
high_brightness = 0.5
|
|
high_color = "#66004D"
|
|
min = 0
|
|
|
|
if(0.40 to 0.50) // Twilight
|
|
low_brightness = 0.6
|
|
low_color = "#66004D"
|
|
|
|
high_brightness = 0.8
|
|
high_color = "#CC3300"
|
|
min = 0.40
|
|
|
|
if(0.50 to 0.70) // Sunrise/set
|
|
low_brightness = 0.8
|
|
low_color = "#CC3300"
|
|
|
|
high_brightness = 0.9
|
|
high_color = "#FF9933"
|
|
min = 0.50
|
|
|
|
if(0.70 to 1.00) // Noon
|
|
low_brightness = 0.9
|
|
low_color = "#DDDDDD"
|
|
|
|
high_brightness = 1.0
|
|
high_color = "#FFFFFF"
|
|
min = 0.70
|
|
|
|
var/interpolate_weight = (abs(min - sun_position)) * 4
|
|
var/weather_light_modifier = 1
|
|
if(weather_holder && weather_holder.current_weather)
|
|
weather_light_modifier = weather_holder.current_weather.light_modifier
|
|
|
|
var/new_brightness = (LERP(low_brightness, high_brightness, interpolate_weight) ) * weather_light_modifier
|
|
|
|
var/new_color = null
|
|
if(weather_holder && weather_holder.current_weather && weather_holder.current_weather.light_color)
|
|
new_color = weather_holder.current_weather.light_color
|
|
else
|
|
var/list/low_color_list = hex2rgb(low_color)
|
|
var/low_r = low_color_list[1]
|
|
var/low_g = low_color_list[2]
|
|
var/low_b = low_color_list[3]
|
|
|
|
var/list/high_color_list = hex2rgb(high_color)
|
|
var/high_r = high_color_list[1]
|
|
var/high_g = high_color_list[2]
|
|
var/high_b = high_color_list[3]
|
|
|
|
var/new_r = LERP(low_r, high_r, interpolate_weight)
|
|
var/new_g = LERP(low_g, high_g, interpolate_weight)
|
|
var/new_b = LERP(low_b, high_b, interpolate_weight)
|
|
|
|
new_color = rgb(new_r, new_g, new_b)
|
|
|
|
spawn(1)
|
|
update_sun_deferred(new_brightness, new_color)
|
|
|
|
// We're gonna pretend there are 32 hours in a Sif day instead of 32.64 for the purposes of not losing sanity. We lose 38m 24s but the alternative is a path to madness.
|
|
/datum/time/sif
|
|
seconds_in_day = 60 * 60 * 32 * 10 // 115,200 seconds. If we did 32.64 hours/day it would be around 117,504 seconds instead.
|
|
|
|
// Returns the time datum of Sif.
|
|
/proc/get_sif_time()
|
|
if(planet_sif)
|
|
return planet_sif.current_time
|
|
|
|
//Weather definitions
|
|
/datum/weather_holder/sif
|
|
temperature = T0C
|
|
allowed_weather_types = list(
|
|
WEATHER_CLEAR = new /datum/weather/sif/clear(),
|
|
WEATHER_OVERCAST = new /datum/weather/sif/overcast(),
|
|
WEATHER_LIGHT_SNOW = new /datum/weather/sif/light_snow(),
|
|
WEATHER_SNOW = new /datum/weather/sif/snow(),
|
|
WEATHER_BLIZZARD = new /datum/weather/sif/blizzard(),
|
|
WEATHER_RAIN = new /datum/weather/sif/rain(),
|
|
WEATHER_STORM = new /datum/weather/sif/storm(),
|
|
WEATHER_HAIL = new /datum/weather/sif/hail(),
|
|
WEATHER_BLOOD_MOON = new /datum/weather/sif/blood_moon(),
|
|
WEATHER_EMBERFALL = new /datum/weather/sif/emberfall(),
|
|
WEATHER_ASH_STORM = new /datum/weather/sif/ash_storm(),
|
|
WEATHER_FALLOUT = new /datum/weather/sif/fallout()
|
|
)
|
|
roundstart_weather_chances = list(
|
|
WEATHER_CLEAR = 30,
|
|
WEATHER_OVERCAST = 30,
|
|
WEATHER_LIGHT_SNOW = 20,
|
|
WEATHER_SNOW = 5,
|
|
WEATHER_BLIZZARD = 5,
|
|
WEATHER_RAIN = 5,
|
|
WEATHER_STORM = 2.5,
|
|
WEATHER_HAIL = 2.5
|
|
)
|
|
|
|
/datum/weather/sif
|
|
name = "sif base"
|
|
temp_high = 283.15 // 10c
|
|
temp_low = 263.15 // -10c
|
|
|
|
/datum/weather/sif/clear
|
|
name = "clear"
|
|
transition_chances = list(
|
|
WEATHER_CLEAR = 60,
|
|
WEATHER_OVERCAST = 40
|
|
)
|
|
transition_messages = list(
|
|
"The sky clears up.",
|
|
"The sky is visible.",
|
|
"The weather is calm."
|
|
)
|
|
sky_visible = TRUE
|
|
observed_message = "The sky is clear."
|
|
|
|
outdoor_sounds_type = /datum/looping_sound/weather/wind/gentle
|
|
indoor_sounds_type = /datum/looping_sound/weather/wind/gentle/indoors
|
|
|
|
/datum/weather/sif/overcast
|
|
name = "overcast"
|
|
light_modifier = 0.8
|
|
transition_chances = list(
|
|
WEATHER_CLEAR = 25,
|
|
WEATHER_OVERCAST = 50,
|
|
WEATHER_LIGHT_SNOW = 10,
|
|
WEATHER_SNOW = 5,
|
|
WEATHER_RAIN = 5,
|
|
WEATHER_HAIL = 5
|
|
)
|
|
observed_message = "It is overcast, all you can see are clouds."
|
|
transition_messages = list(
|
|
"All you can see above are clouds.",
|
|
"Clouds cut off your view of the sky.",
|
|
"It's very cloudy."
|
|
)
|
|
|
|
outdoor_sounds_type = /datum/looping_sound/weather/wind/gentle
|
|
indoor_sounds_type = /datum/looping_sound/weather/wind/gentle/indoors
|
|
|
|
/datum/weather/sif/light_snow
|
|
name = "light snow"
|
|
icon_state = "snowfall_light"
|
|
temp_high = T0C // 0c
|
|
temp_low = 258.15 // -15c
|
|
light_modifier = 0.7
|
|
transition_chances = list(
|
|
WEATHER_OVERCAST = 20,
|
|
WEATHER_LIGHT_SNOW = 50,
|
|
WEATHER_SNOW = 25,
|
|
WEATHER_HAIL = 5
|
|
)
|
|
observed_message = "It is snowing lightly."
|
|
transition_messages = list(
|
|
"Small snowflakes begin to fall from above.",
|
|
"It begins to snow lightly.",
|
|
)
|
|
|
|
outdoor_sounds_type = /datum/looping_sound/weather/wind/gentle
|
|
indoor_sounds_type = /datum/looping_sound/weather/wind/gentle/indoors
|
|
|
|
/datum/weather/sif/snow
|
|
name = "moderate snow"
|
|
icon_state = "snowfall_med"
|
|
temp_high = T0C // 0c
|
|
temp_low = 243.15 // -30c
|
|
wind_high = 2
|
|
wind_low = 0
|
|
light_modifier = 0.5
|
|
flight_failure_modifier = 5
|
|
transition_chances = list(
|
|
WEATHER_LIGHT_SNOW = 20,
|
|
WEATHER_SNOW = 50,
|
|
WEATHER_BLIZZARD = 20,
|
|
WEATHER_HAIL = 5,
|
|
WEATHER_OVERCAST = 5
|
|
)
|
|
observed_message = "It is snowing."
|
|
transition_messages = list(
|
|
"It's starting to snow.",
|
|
"The air feels much colder as snowflakes fall from above."
|
|
)
|
|
outdoor_sounds_type = /datum/looping_sound/weather/outside_snow
|
|
indoor_sounds_type = /datum/looping_sound/weather/inside_snow
|
|
|
|
/*
|
|
/datum/weather/sif/snow/process_effects()
|
|
..()
|
|
for(var/turf/simulated/floor/outdoors/snow/S as anything in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either
|
|
if(S.z in holder.our_planet.expected_z_levels)
|
|
for(var/dir_checked in cardinal)
|
|
var/turf/simulated/floor/T = get_step(S, dir_checked)
|
|
if(istype(T))
|
|
if(istype(T, /turf/simulated/floor/outdoors) && prob(33))
|
|
T.chill()
|
|
*/
|
|
|
|
/datum/weather/sif/blizzard
|
|
name = "blizzard"
|
|
icon_state = "snowfall_heavy"
|
|
temp_high = 243.15 // -30c
|
|
temp_low = 233.15 // -40c
|
|
wind_high = 4
|
|
wind_low = 2
|
|
light_modifier = 0.3
|
|
flight_failure_modifier = 10
|
|
transition_chances = list(
|
|
WEATHER_SNOW = 45,
|
|
WEATHER_BLIZZARD = 40,
|
|
WEATHER_HAIL = 10,
|
|
WEATHER_OVERCAST = 5
|
|
)
|
|
observed_message = "A blizzard blows snow everywhere."
|
|
transition_messages = list(
|
|
"Strong winds howl around you as a blizzard appears.",
|
|
"It starts snowing heavily, and it feels extremly cold now."
|
|
)
|
|
outdoor_sounds_type = /datum/looping_sound/weather/outside_blizzard
|
|
indoor_sounds_type = /datum/looping_sound/weather/inside_blizzard
|
|
|
|
/*
|
|
/datum/weather/sif/blizzard/process_effects()
|
|
..()
|
|
for(var/turf/simulated/floor/outdoors/snow/S as anything in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either
|
|
if(S.z in holder.our_planet.expected_z_levels)
|
|
for(var/dir_checked in cardinal)
|
|
var/turf/simulated/floor/T = get_step(S, dir_checked)
|
|
if(istype(T))
|
|
if(istype(T, /turf/simulated/floor/outdoors) && prob(50))
|
|
T.chill()
|
|
*/
|
|
|
|
/datum/weather/sif/rain
|
|
name = "rain"
|
|
icon_state = "rain"
|
|
wind_high = 2
|
|
wind_low = 1
|
|
light_modifier = 0.5
|
|
effect_message = "<span class='warning'>Rain falls on you.</span>"
|
|
|
|
transition_chances = list(
|
|
WEATHER_OVERCAST = 25,
|
|
WEATHER_LIGHT_SNOW = 10,
|
|
WEATHER_RAIN = 50,
|
|
WEATHER_STORM = 10,
|
|
WEATHER_HAIL = 5
|
|
)
|
|
observed_message = "It is raining."
|
|
transition_messages = list(
|
|
"The sky is dark, and rain falls down upon you."
|
|
)
|
|
outdoor_sounds_type = /datum/looping_sound/weather/rain
|
|
indoor_sounds_type = /datum/looping_sound/weather/rain/indoors
|
|
|
|
/datum/weather/sif/rain/process_effects()
|
|
..()
|
|
for(var/mob/living/L as anything in living_mob_list)
|
|
if(L.z in holder.our_planet.expected_z_levels)
|
|
var/turf/T = get_turf(L)
|
|
if(!T.is_outdoors())
|
|
continue // They're indoors, so no need to rain on them.
|
|
|
|
// If they have an open umbrella, it'll guard from rain
|
|
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
|
|
if(!istype(U) || !U.open)
|
|
U = L.get_inactive_hand()
|
|
|
|
if(istype(U) && U.open)
|
|
if(show_message)
|
|
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella.</span>")
|
|
continue
|
|
|
|
L.water_act(1)
|
|
if(show_message)
|
|
to_chat(L, effect_message)
|
|
|
|
/datum/weather/sif/storm
|
|
name = "storm"
|
|
icon_state = "storm"
|
|
temp_high = 243.15 // -30c
|
|
temp_low = 233.15 // -40c
|
|
wind_high = 4
|
|
wind_low = 2
|
|
light_modifier = 0.3
|
|
flight_failure_modifier = 10
|
|
effect_message = "<span class='warning'>Rain falls on you, drenching you in water.</span>"
|
|
|
|
var/next_lightning_strike = 0 // world.time when lightning will strike.
|
|
var/min_lightning_cooldown = 5 SECONDS
|
|
var/max_lightning_cooldown = 1 MINUTE
|
|
observed_message = "An intense storm pours down over the region."
|
|
transition_messages = list(
|
|
"You feel intense winds hit you as the weather takes a turn for the worst.",
|
|
"Loud thunder is heard in the distance.",
|
|
"A bright flash heralds the approach of a storm."
|
|
)
|
|
outdoor_sounds_type = /datum/looping_sound/weather/storm
|
|
indoor_sounds_type = /datum/looping_sound/weather/storm/indoors
|
|
// CHOMPEdit - change weather sounds to proper storm sounds
|
|
|
|
transition_chances = list(
|
|
WEATHER_RAIN = 45,
|
|
WEATHER_STORM = 40,
|
|
WEATHER_HAIL = 10,
|
|
WEATHER_OVERCAST = 5
|
|
)
|
|
|
|
/datum/weather/sif/storm/process_effects()
|
|
..()
|
|
for(var/mob/living/L as anything in living_mob_list)
|
|
if(L.z in holder.our_planet.expected_z_levels)
|
|
var/turf/T = get_turf(L)
|
|
if(!T.is_outdoors())
|
|
continue // They're indoors, so no need to rain on them.
|
|
|
|
// If they have an open umbrella, it'll guard from rain
|
|
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
|
|
if(!istype(U) || !U.open)
|
|
U = L.get_inactive_hand()
|
|
|
|
if(istype(U) && U.open)
|
|
if(show_message)
|
|
to_chat(L, "<span class='notice'>Rain showers loudly onto your umbrella!</span>")
|
|
continue
|
|
|
|
|
|
L.water_act(2)
|
|
if(show_message)
|
|
to_chat(L, effect_message)
|
|
|
|
handle_lightning()
|
|
|
|
// This gets called to do lightning periodically.
|
|
// There is a seperate function to do the actual lightning strike, so that badmins can play with it.
|
|
/datum/weather/sif/storm/proc/handle_lightning()
|
|
if(world.time < next_lightning_strike)
|
|
return // It's too soon to strike again.
|
|
next_lightning_strike = world.time + rand(min_lightning_cooldown, max_lightning_cooldown)
|
|
var/turf/T = pick(holder.our_planet.planet_floors) // This has the chance to 'strike' the sky, but that might be a good thing, to scare reckless pilots.
|
|
lightning_strike(T)
|
|
|
|
/datum/weather/sif/hail
|
|
name = "hail"
|
|
icon_state = "hail"
|
|
temp_high = T0C // 0c
|
|
temp_low = 243.15 // -30c
|
|
light_modifier = 0.3
|
|
flight_failure_modifier = 15
|
|
timer_low_bound = 2
|
|
timer_high_bound = 5
|
|
effect_message = "<span class='warning'>The hail smacks into you!</span>"
|
|
|
|
transition_chances = list(
|
|
WEATHER_RAIN = 45,
|
|
WEATHER_STORM = 40,
|
|
WEATHER_HAIL = 10,
|
|
WEATHER_OVERCAST = 5
|
|
)
|
|
observed_message = "Ice is falling from the sky."
|
|
transition_messages = list(
|
|
"Ice begins to fall from the sky.",
|
|
"It begins to hail.",
|
|
"An intense chill is felt, and chunks of ice start to fall from the sky, towards you."
|
|
)
|
|
|
|
/datum/weather/sif/hail/process_effects()
|
|
..()
|
|
for(var/mob/living/carbon/H as anything in human_mob_list)
|
|
if(H.z in holder.our_planet.expected_z_levels)
|
|
var/turf/T = get_turf(H)
|
|
if(!T.is_outdoors())
|
|
continue // They're indoors, so no need to pelt them with ice.
|
|
|
|
// If they have an open umbrella, it'll guard from hail
|
|
var/obj/item/weapon/melee/umbrella/U = H.get_active_hand()
|
|
if(!istype(U) || !U.open)
|
|
U = H.get_inactive_hand()
|
|
|
|
if(istype(U) && U.open)
|
|
if(show_message)
|
|
to_chat(H, "<span class='notice'>Hail patters onto your umbrella.</span>")
|
|
continue
|
|
|
|
var/target_zone = pick(BP_ALL)
|
|
var/amount_blocked = H.run_armor_check(target_zone, "melee")
|
|
var/amount_soaked = H.get_armor_soak(target_zone, "melee")
|
|
|
|
var/damage = rand(1,3)
|
|
|
|
if(amount_blocked >= 30)
|
|
continue // No need to apply damage. Hardhats are 30. They should probably protect you from hail on your head.
|
|
//Voidsuits are likewise 40, and riot, 80. Clothes are all less than 30.
|
|
|
|
if(amount_soaked >= damage)
|
|
continue // No need to apply damage.
|
|
|
|
H.apply_damage(damage, BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
|
|
if(show_message)
|
|
to_chat(H, effect_message)
|
|
|
|
|
|
// These never happen naturally, and are for adminbuse.
|
|
|
|
// A culty weather.
|
|
/datum/weather/sif/blood_moon
|
|
name = "blood moon"
|
|
light_modifier = 0.5
|
|
light_color = "#FF0000"
|
|
flight_failure_modifier = 25
|
|
transition_chances = list(
|
|
WEATHER_BLOODMOON = 100
|
|
)
|
|
observed_message = "Everything is red. Something really wrong is going on."
|
|
transition_messages = list(
|
|
"The sky turns blood red!"
|
|
)
|
|
outdoor_sounds_type = /datum/looping_sound/weather/wind
|
|
indoor_sounds_type = /datum/looping_sound/weather/wind/indoors
|
|
|
|
// Ash and embers fall forever, such as from a volcano or something.
|
|
/datum/weather/sif/emberfall
|
|
name = "emberfall"
|
|
icon_state = "ashfall_light"
|
|
light_modifier = 0.7
|
|
light_color = "#880000"
|
|
temp_high = 293.15 // 20c
|
|
temp_low = 283.15 // 10c
|
|
flight_failure_modifier = 20
|
|
transition_chances = list(
|
|
WEATHER_EMBERFALL = 100
|
|
)
|
|
observed_message = "Soot, ash, and embers float down from above."
|
|
transition_messages = list(
|
|
"Gentle embers waft down around you like grotesque snow."
|
|
)
|
|
outdoor_sounds_type = /datum/looping_sound/weather/wind
|
|
indoor_sounds_type = /datum/looping_sound/weather/wind/indoors
|
|
|
|
// Like the above but a lot more harmful.
|
|
/datum/weather/sif/ash_storm
|
|
name = "ash storm"
|
|
icon_state = "ashfall_heavy"
|
|
light_modifier = 0.1
|
|
light_color = "#FF0000"
|
|
temp_high = 323.15 // 50c
|
|
temp_low = 313.15 // 40c
|
|
wind_high = 6
|
|
wind_low = 3
|
|
flight_failure_modifier = 50
|
|
transition_chances = list(
|
|
WEATHER_ASH_STORM = 100
|
|
)
|
|
observed_message = "All that can be seen is black smoldering ash."
|
|
transition_messages = list(
|
|
"Smoldering clouds of scorching ash billow down around you!"
|
|
)
|
|
// Lets recycle.
|
|
outdoor_sounds_type = /datum/looping_sound/weather/outside_blizzard
|
|
indoor_sounds_type = /datum/looping_sound/weather/inside_blizzard
|
|
|
|
/datum/weather/sif/ash_storm/process_effects()
|
|
..()
|
|
for(var/mob/living/L as anything in living_mob_list)
|
|
if(L.z in holder.our_planet.expected_z_levels)
|
|
var/turf/T = get_turf(L)
|
|
if(!T.is_outdoors())
|
|
continue // They're indoors, so no need to burn them with ash.
|
|
|
|
L.inflict_heat_damage(rand(1, 3))
|
|
|
|
|
|
// Totally radical.
|
|
/datum/weather/sif/fallout
|
|
name = "fallout"
|
|
icon_state = "fallout"
|
|
light_modifier = 0.7
|
|
light_color = "#CCFFCC"
|
|
flight_failure_modifier = 30
|
|
transition_chances = list(
|
|
WEATHER_FALLOUT = 100
|
|
)
|
|
observed_message = "Radioactive soot and ash rains down from the heavens."
|
|
transition_messages = list(
|
|
"Radioactive soot and ash start to float down around you, contaminating whatever they touch."
|
|
)
|
|
outdoor_sounds_type = /datum/looping_sound/weather/wind
|
|
indoor_sounds_type = /datum/looping_sound/weather/wind/indoors
|
|
|
|
// How much radiation a mob gets while on an outside tile.
|
|
var/direct_rad_low = RAD_LEVEL_LOW
|
|
var/direct_rad_high = RAD_LEVEL_MODERATE
|
|
|
|
// How much radiation is bursted onto a random tile near a mob.
|
|
var/fallout_rad_low = RAD_LEVEL_HIGH
|
|
var/fallout_rad_high = RAD_LEVEL_VERY_HIGH
|
|
|
|
/datum/weather/sif/fallout/process_effects()
|
|
..()
|
|
for(var/mob/living/L as anything in living_mob_list)
|
|
if(L.z in holder.our_planet.expected_z_levels)
|
|
irradiate_nearby_turf(L)
|
|
var/turf/T = get_turf(L)
|
|
if(!T.is_outdoors())
|
|
continue // They're indoors, so no need to irradiate them with fallout.
|
|
|
|
L.rad_act(rand(direct_rad_low, direct_rad_high))
|
|
|
|
// This makes random tiles near people radioactive for awhile.
|
|
// Tiles far away from people are left alone, for performance.
|
|
/datum/weather/sif/fallout/proc/irradiate_nearby_turf(mob/living/L)
|
|
if(!istype(L))
|
|
return
|
|
var/list/turfs = RANGE_TURFS(world.view, L)
|
|
var/turf/T = pick(turfs) // We get one try per tick.
|
|
if(!istype(T))
|
|
return
|
|
if(T.is_outdoors())
|
|
SSradiation.radiate(T, rand(fallout_rad_low, fallout_rad_high))
|