mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Vore Updates and merges
This commit is contained in:
@@ -21,19 +21,34 @@
|
||||
var/list/turf/simulated/floor/planet_floors = list()
|
||||
var/list/turf/unsimulated/wall/planetary/planet_walls = list()
|
||||
|
||||
|
||||
var/needs_work = 0 // Bitflags to signal to the planet controller these need (properly deferrable) work. Flags defined in controller.
|
||||
|
||||
var/sun_name = "the sun" // For flavor.
|
||||
|
||||
var/moon_name = null // Purely for flavor. Null means no moon exists.
|
||||
var/moon_phase = null // Set if above is defined.
|
||||
|
||||
/datum/planet/New()
|
||||
..()
|
||||
weather_holder = new(src)
|
||||
current_time = current_time.make_random_time()
|
||||
if(moon_name)
|
||||
moon_phase = pick(list(
|
||||
MOON_PHASE_NEW_MOON,
|
||||
MOON_PHASE_WAXING_CRESCENT,
|
||||
MOON_PHASE_FIRST_QUARTER,
|
||||
MOON_PHASE_WAXING_GIBBOUS,
|
||||
MOON_PHASE_FULL_MOON,
|
||||
MOON_PHASE_WANING_GIBBOUS,
|
||||
MOON_PHASE_LAST_QUARTER,
|
||||
MOON_PHASE_WANING_CRESCENT
|
||||
))
|
||||
update_sun()
|
||||
|
||||
/datum/planet/proc/process(last_fire)
|
||||
if(current_time)
|
||||
var/difference = world.time - last_fire
|
||||
current_time = current_time.add_seconds(difference SECONDS)
|
||||
current_time = current_time.add_seconds((difference / 10) * PLANET_TIME_MODIFIER)
|
||||
update_weather() // We update this first, because some weather types decease the brightness of the sun.
|
||||
if(sun_last_process <= world.time - sun_process_interval)
|
||||
update_sun()
|
||||
|
||||
@@ -12,6 +12,9 @@ var/datum/planet/sif/planet_sif = null
|
||||
// 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
|
||||
@@ -131,7 +134,7 @@ var/datum/planet/sif/planet_sif = null
|
||||
WEATHER_HAIL = 2.5
|
||||
)
|
||||
|
||||
datum/weather/sif
|
||||
/datum/weather/sif
|
||||
name = "sif base"
|
||||
temp_high = 283.15 // 10c
|
||||
temp_low = 263.15 // -10c
|
||||
@@ -142,6 +145,13 @@ datum/weather/sif
|
||||
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."
|
||||
|
||||
/datum/weather/sif/overcast
|
||||
name = "overcast"
|
||||
@@ -154,6 +164,12 @@ datum/weather/sif
|
||||
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."
|
||||
)
|
||||
|
||||
/datum/weather/sif/light_snow
|
||||
name = "light snow"
|
||||
@@ -167,6 +183,11 @@ datum/weather/sif
|
||||
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.",
|
||||
)
|
||||
|
||||
/datum/weather/sif/snow
|
||||
name = "moderate snow"
|
||||
@@ -182,6 +203,11 @@ datum/weather/sif
|
||||
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."
|
||||
)
|
||||
|
||||
/datum/weather/sif/snow/process_effects()
|
||||
..()
|
||||
@@ -206,6 +232,11 @@ datum/weather/sif
|
||||
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."
|
||||
)
|
||||
|
||||
/datum/weather/sif/blizzard/process_effects()
|
||||
..()
|
||||
@@ -230,6 +261,10 @@ datum/weather/sif
|
||||
WEATHER_STORM = 10,
|
||||
WEATHER_HAIL = 5
|
||||
)
|
||||
observed_message = "It is raining."
|
||||
transition_messages = list(
|
||||
"The sky is dark, and rain falls down upon you."
|
||||
)
|
||||
|
||||
/datum/weather/sif/rain/process_effects()
|
||||
..()
|
||||
@@ -244,13 +279,13 @@ datum/weather/sif
|
||||
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
|
||||
if(U.open)
|
||||
if(show_message)
|
||||
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
|
||||
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella.</span>")
|
||||
continue
|
||||
else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
|
||||
var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand()
|
||||
if(U.open)
|
||||
if(show_message)
|
||||
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
|
||||
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella.</span>")
|
||||
continue
|
||||
|
||||
L.water_act(1)
|
||||
@@ -264,6 +299,17 @@ datum/weather/sif
|
||||
temp_low = 233.15 // -40c
|
||||
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."
|
||||
)
|
||||
|
||||
|
||||
transition_chances = list(
|
||||
@@ -281,22 +327,52 @@ datum/weather/sif
|
||||
if(!T.outdoors)
|
||||
continue // They're indoors, so no need to rain on them.
|
||||
|
||||
// If they have an open umbrella, it'll get stolen by the wind
|
||||
// Lazy wind code
|
||||
if(prob(10))
|
||||
if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella))
|
||||
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
|
||||
if(U.open)
|
||||
to_chat(L, "<span class='danger'>You struggle to keep hold of your umbrella!</span>")
|
||||
L.Stun(20) // This is not nearly as long as it seems
|
||||
playsound(L, 'sound/effects/rustle1.ogg', 100, 1) // Closest sound I've got to "Umbrella in the wind"
|
||||
else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
|
||||
var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand()
|
||||
if(U.open)
|
||||
to_chat(L, "<span class='danger'>A gust of wind yanks the umbrella from your hand!</span>")
|
||||
playsound(L, 'sound/effects/rustle1.ogg', 100, 1)
|
||||
L.drop_from_inventory(U)
|
||||
U.toggle_umbrella()
|
||||
U.throw_at(get_edge_target_turf(U, pick(alldirs)), 8, 1, L)
|
||||
|
||||
// If they have an open umbrella, it'll guard from rain
|
||||
if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella))
|
||||
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
|
||||
if(U.open)
|
||||
to_chat(L, "<span class='warning'>A gust of wind yanks the umbrella from your hand!</span>")
|
||||
L.drop_from_inventory(U)
|
||||
U.throw_at(get_edge_target_turf(U, pick(alldirs)), 8, 1, L)
|
||||
if(show_message)
|
||||
to_chat(L, "<span class='notice'>Rain showers loudly onto your umbrella!</span>")
|
||||
continue
|
||||
else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
|
||||
var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand()
|
||||
if(U.open)
|
||||
to_chat(L, "<span class='warning'>A gust of wind yanks the umbrella from your hand!</span>")
|
||||
L.drop_from_inventory(U)
|
||||
U.throw_at(get_edge_target_turf(U, pick(alldirs)), 8, 1, L)
|
||||
if(show_message)
|
||||
to_chat(L, "<span class='notice'>Rain showers loudly onto your umbrella!</span>")
|
||||
continue
|
||||
|
||||
|
||||
L.water_act(2)
|
||||
to_chat(L, "<span class='warning'>Rain falls on you, drenching you in water.</span>")
|
||||
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"
|
||||
@@ -315,6 +391,12 @@ datum/weather/sif
|
||||
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()
|
||||
..()
|
||||
@@ -361,3 +443,7 @@ datum/weather/sif
|
||||
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!"
|
||||
)
|
||||
@@ -1,15 +1,17 @@
|
||||
/datum/weather_holder
|
||||
var/datum/planet/our_planet = null
|
||||
var/datum/weather/current_weather = null
|
||||
var/temperature = T20C
|
||||
var/wind_dir = 0
|
||||
var/wind_speed = 0
|
||||
var/list/allowed_weather_types = list()
|
||||
var/list/roundstart_weather_chances = list()
|
||||
var/next_weather_shift = null
|
||||
var/datum/planet/our_planet = null // Reference to the planet datum that holds this datum.
|
||||
var/datum/weather/current_weather = null // The current weather that is affecting the planet.
|
||||
var/temperature = T20C // The temperature to set planetary walls to.
|
||||
var/wind_dir = 0 // Not implemented.
|
||||
var/wind_speed = 0 // Not implemented.
|
||||
var/list/allowed_weather_types = list() // Assoc list of weather identifiers, containing the actual weather datum.
|
||||
var/list/roundstart_weather_chances = list() // Assoc list of weather identifiers and their odds of being picked to happen at roundstart.
|
||||
var/next_weather_shift = null // world.time when the weather subsystem will advance the forecast.
|
||||
var/list/forecast = list() // A list of what the weather will be in the future. This allows it to be pre-determined and planned around.
|
||||
|
||||
// Holds the weather icon, using vis_contents. Documentation says an /atom/movable is required for placing inside another atom's vis_contents.
|
||||
var/atom/movable/weather_visuals/visuals = null
|
||||
var/atom/movable/weather_visuals/special/special_visuals = null
|
||||
|
||||
/datum/weather_holder/New(var/source)
|
||||
..()
|
||||
@@ -19,31 +21,79 @@
|
||||
if(istype(W))
|
||||
W.holder = src
|
||||
visuals = new()
|
||||
special_visuals = new()
|
||||
|
||||
/datum/weather_holder/proc/change_weather(var/new_weather)
|
||||
var/old_light_modifier = null
|
||||
var/old_weather = null
|
||||
if(current_weather)
|
||||
old_light_modifier = current_weather.light_modifier // We store the old one, so we can determine if recalculating the sun is needed.
|
||||
old_weather = current_weather
|
||||
current_weather = allowed_weather_types[new_weather]
|
||||
next_weather_shift = world.time + rand(current_weather.timer_low_bound, current_weather.timer_high_bound) MINUTES
|
||||
if(new_weather != old_weather)
|
||||
show_transition_message()
|
||||
|
||||
update_icon_effects()
|
||||
update_temperature()
|
||||
if(old_light_modifier && current_weather.light_modifier != old_light_modifier) // Updating the sun should be done sparingly.
|
||||
our_planet.update_sun()
|
||||
//message_admins("[our_planet.name]'s weather is now [new_weather], with a temperature of [temperature]°K ([temperature - T0C]°C | [temperature * 1.8 - 459.67]°F).") //VOREStation Removal - I like weather, I just don't like hearing about it.
|
||||
log_debug("[our_planet.name]'s weather is now [new_weather], with a temperature of [temperature]°K ([temperature - T0C]°C | [temperature * 1.8 - 459.67]°F).")
|
||||
|
||||
/datum/weather_holder/proc/process()
|
||||
if(world.time >= next_weather_shift)
|
||||
var/new_weather
|
||||
if(!current_weather)
|
||||
new_weather = pickweight(roundstart_weather_chances)
|
||||
if(!current_weather) // Roundstart (hopefully).
|
||||
initialize_weather()
|
||||
else
|
||||
new_weather = pickweight(current_weather.transition_chances)
|
||||
change_weather(new_weather)
|
||||
advance_forecast()
|
||||
else
|
||||
current_weather.process_effects()
|
||||
|
||||
|
||||
|
||||
// Should only have to be called once.
|
||||
/datum/weather_holder/proc/initialize_weather()
|
||||
if(!current_weather)
|
||||
change_weather(get_next_weather())
|
||||
build_forecast()
|
||||
|
||||
// Used to determine what the weather will be soon, in a semi-random fashion.
|
||||
// The forecast is made by calling this repeatively, from the bottom (highest index) of the forecast list.
|
||||
/datum/weather_holder/proc/get_next_weather(var/datum/weather/W)
|
||||
if(!current_weather) // At roundstart, choose a suitable initial weather.
|
||||
return pickweight(roundstart_weather_chances)
|
||||
return pickweight(W.transition_chances)
|
||||
|
||||
/datum/weather_holder/proc/advance_forecast()
|
||||
var/new_weather = forecast[1]
|
||||
forecast.Cut(1, 2) // Remove what we just took out, shortening the list.
|
||||
change_weather(new_weather)
|
||||
build_forecast() // To fill the forecast to the desired length.
|
||||
|
||||
// Creates a list of future weather shifts, that the planet will undergo at some point in the future.
|
||||
// Determining it ahead of time allows for attentive players to plan further ahead, if they can see the forecast.
|
||||
/datum/weather_holder/proc/build_forecast()
|
||||
var/desired_length = 3
|
||||
if(forecast.len >= desired_length)
|
||||
return
|
||||
|
||||
while(forecast.len < desired_length)
|
||||
if(!forecast.len) // If the forecast is empty, the current_weather is used as a base instead.
|
||||
forecast += get_next_weather(current_weather)
|
||||
else
|
||||
var/position = forecast[forecast.len] // Go to the bottom of the list.
|
||||
var/datum/weather/W = allowed_weather_types[position] // Get the actual datum and not a string.
|
||||
var/new_weather = get_next_weather(W) // Get a suitable weather pattern to shift to from this one.
|
||||
forecast += new_weather
|
||||
log_debug("[our_planet.name]'s weather forecast is now '[english_list(forecast, and_text = " then ", final_comma_text = ", ")]'.")
|
||||
|
||||
// Wipes the forecast and regenerates it. Used for when the weather is forcefully changed, such as with admin verbs.
|
||||
/datum/weather_holder/proc/rebuild_forecast()
|
||||
forecast.Cut()
|
||||
build_forecast()
|
||||
|
||||
|
||||
|
||||
/datum/weather_holder/proc/update_icon_effects()
|
||||
visuals.icon_state = current_weather.icon_state
|
||||
|
||||
@@ -55,25 +105,41 @@
|
||||
return allowed_weather_types[desired_type]
|
||||
|
||||
|
||||
/datum/weather_holder/proc/show_transition_message()
|
||||
if(!current_weather.transition_messages.len)
|
||||
return
|
||||
|
||||
var/message = pick(current_weather.transition_messages) // So everyone gets the same message.
|
||||
for(var/mob/M in player_list) // Don't need to care about clientless mobs.
|
||||
if(M.z in our_planet.expected_z_levels)
|
||||
var/turf/T = get_turf(M)
|
||||
if(!T.outdoors)
|
||||
continue
|
||||
to_chat(M, message)
|
||||
|
||||
/datum/weather
|
||||
var/name = "weather base"
|
||||
var/icon = 'icons/effects/weather.dmi'
|
||||
var/icon_state = null // Icon to apply to turf undergoing weather.
|
||||
var/temp_high = T20C
|
||||
var/temp_low = T0C
|
||||
var/temp_high = T20C // Temperature to apply when at noon.
|
||||
var/temp_low = T0C // Temperature to apply when at midnight.
|
||||
var/light_modifier = 1.0 // Lower numbers means more darkness.
|
||||
var/light_color = null // If set, changes how the day/night light looks.
|
||||
var/flight_failure_modifier = 0 // Some types of weather make flying harder, and therefore make crashes more likely.
|
||||
var/transition_chances = list() // Assoc list
|
||||
var/datum/weather_holder/holder = null
|
||||
var/flight_failure_modifier = 0 // Some types of weather make flying harder, and therefore make crashes more likely. (This is not implemented)
|
||||
var/transition_chances = list() // Assoc list of weather identifiers and the odds to shift to a specific type of weather. Can contain its own identifier to prolong it.
|
||||
var/datum/weather_holder/holder = null // Reference to the datum that manages the planet's weather.
|
||||
var/timer_low_bound = 5 // How long this weather must run before it tries to change, in minutes
|
||||
var/timer_high_bound = 10 // How long this weather can run before it tries to change, in minutes
|
||||
var/sky_visible = FALSE // If the sky can be clearly seen while this is occuring, used for flavor text when looking up.
|
||||
|
||||
var/effect_message = null // Should be a string, this is what is shown to a mob caught in the weather
|
||||
var/last_message = 0 // Keeps track of when the weather last tells EVERY player it's hitting them
|
||||
var/message_delay = 10 SECONDS // Delay in between weather hit messages
|
||||
var/show_message = FALSE // Is set to TRUE and plays the messsage every [message_delay]
|
||||
|
||||
var/list/transition_messages = list()// List of messages shown to all outdoor mobs when this weather is transitioned to, for flavor. Not shown if already this weather.
|
||||
var/observed_message = null // What is shown to a player 'examining' the weather.
|
||||
|
||||
/datum/weather/proc/process_effects()
|
||||
show_message = FALSE // Need to reset the show_message var, just in case
|
||||
if(effect_message) // Only bother with the code below if we actually need to display something
|
||||
@@ -87,3 +153,8 @@
|
||||
icon = 'icons/effects/weather.dmi'
|
||||
mouse_opacity = 0
|
||||
plane = PLANE_PLANETLIGHTING
|
||||
|
||||
// This is for special effects for specific types of weather, such as lightning flashes in a storm.
|
||||
// It's a seperate object to allow the use of flick().
|
||||
/atom/movable/weather_visuals/special
|
||||
plane = PLANE_LIGHTING_ABOVE
|
||||
Reference in New Issue
Block a user