mirror of
https://github.com/CHOMPstation/CHOMPstation.git
synced 2026-08-27 22:16:23 +01:00
Merge pull request #3001 from Neerti/2/2/2017_planet_stuff
Adds framework for planetary maps
This commit is contained in:
@@ -200,7 +200,9 @@ var/list/admin_verbs_debug = list(
|
||||
/client/proc/toggle_debug_logs,
|
||||
/client/proc/admin_ghost, //allows us to ghost/reenter body at will,
|
||||
/datum/admins/proc/view_runtimes,
|
||||
/client/proc/show_gm_status
|
||||
/client/proc/show_gm_status,
|
||||
/datum/admins/proc/change_weather,
|
||||
/datum/admins/proc/change_time
|
||||
)
|
||||
|
||||
var/list/admin_verbs_paranoid_debug = list(
|
||||
|
||||
@@ -968,3 +968,46 @@
|
||||
return
|
||||
|
||||
error_cache.showTo(usr)
|
||||
|
||||
/datum/admins/proc/change_weather()
|
||||
set category = "Debug"
|
||||
set name = "Change Weather"
|
||||
set desc = "Changes the current weather."
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in list(planet_sif)
|
||||
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
|
||||
if(new_weather)
|
||||
planet.weather_holder.change_weather(new_weather)
|
||||
var/log = "[key_name(src)] changed [planet.name]'s weather to [new_weather]."
|
||||
message_admins(log)
|
||||
log_admin(log)
|
||||
|
||||
/datum/admins/proc/change_time()
|
||||
set category = "Debug"
|
||||
set name = "Change Planet Time"
|
||||
set desc = "Changes the time of a planet."
|
||||
|
||||
if(!check_rights(R_DEBUG))
|
||||
return
|
||||
|
||||
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in list(planet_sif)
|
||||
|
||||
var/datum/time/current_time_datum = planet.current_time
|
||||
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
|
||||
if(!isnull(new_hour))
|
||||
var/new_minute = input(usr, "What minute do you want to change to?", "Change Time", text2num(current_time_datum.show_time("mm")) ) as null|num
|
||||
if(!isnull(new_minute))
|
||||
var/type_needed = current_time_datum.type
|
||||
var/datum/time/new_time = new type_needed()
|
||||
new_time = new_time.add_hours(new_hour)
|
||||
new_time = new_time.add_minutes(new_minute)
|
||||
planet.current_time = new_time
|
||||
spawn(1)
|
||||
planet.update_sun()
|
||||
|
||||
var/log = "[key_name(src)] changed [planet.name]'s time to [planet.current_time.show_time("hh:mm")]."
|
||||
message_admins(log)
|
||||
log_admin(log)
|
||||
@@ -146,3 +146,6 @@
|
||||
new/datum/stack_recipe("white folder", /obj/item/weapon/folder/white), \
|
||||
new/datum/stack_recipe("yellow folder", /obj/item/weapon/folder/yellow), \
|
||||
))
|
||||
|
||||
/material/snow/generate_recipes()
|
||||
return // Snowmen and snowballs may come here later.
|
||||
@@ -189,6 +189,12 @@
|
||||
icon_state = "sheet-card"
|
||||
default_type = "cardboard"
|
||||
|
||||
/obj/item/stack/material/snow
|
||||
name = "snow"
|
||||
desc = "The temptation to build a snowfort rises."
|
||||
icon_state = "sheet-snow"
|
||||
default_type = "snow"
|
||||
|
||||
/obj/item/stack/material/leather
|
||||
name = "leather"
|
||||
desc = "The by-product of mob grinding."
|
||||
|
||||
@@ -628,6 +628,22 @@ var/list/name_to_material
|
||||
door_icon_base = "wood"
|
||||
destruction_desc = "crumples"
|
||||
|
||||
/material/snow
|
||||
name = "snow"
|
||||
stack_type = /obj/item/stack/material/snow
|
||||
flags = MATERIAL_BRITTLE
|
||||
icon_base = "solid"
|
||||
icon_reinf = "reinf_over"
|
||||
icon_colour = "#FFFFFF"
|
||||
integrity = 1
|
||||
hardness = 1
|
||||
weight = 1
|
||||
stack_origin_tech = list(TECH_MATERIAL = 1)
|
||||
melting_point = T0C+1
|
||||
destruction_desc = "crumples"
|
||||
sheet_singular_name = "pile"
|
||||
sheet_plural_name = "piles"
|
||||
|
||||
/material/cloth //todo
|
||||
name = "cloth"
|
||||
stack_origin_tech = list(TECH_MATERIAL = 2)
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
|
||||
var/datum/gas_mixture/environment
|
||||
if(loc)
|
||||
environment = loc.return_air_for_internal_lifeform()
|
||||
environment = loc.return_air_for_internal_lifeform(src)
|
||||
|
||||
if(environment)
|
||||
breath = environment.remove_volume(volume_needed)
|
||||
|
||||
@@ -457,7 +457,7 @@
|
||||
/mob/living/carbon/proc/should_have_organ(var/organ_check)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/proc/can_feel_pain(var/check_organ)
|
||||
/mob/living/carbon/can_feel_pain(var/check_organ)
|
||||
if(isSynthetic())
|
||||
return 0
|
||||
return !(species.flags & NO_PAIN)
|
||||
@@ -76,12 +76,15 @@
|
||||
var/obj/item/pulled = pulling
|
||||
tally += max(pulled.slowdown, 0)
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(T && T.movement_cost)
|
||||
tally += T.movement_cost
|
||||
|
||||
if(CE_SPEEDBOOST in chem_effects)
|
||||
if (tally >= 0) // cut any penalties in half
|
||||
tally = tally/2
|
||||
tally -= 1 // give 'em a buff on top.
|
||||
|
||||
return (tally+config.human_delay)
|
||||
return (tally+config.human_delay)
|
||||
|
||||
/mob/living/carbon/human/Process_Spacemove(var/check_drift = 0)
|
||||
//Can we act?
|
||||
|
||||
@@ -305,3 +305,7 @@
|
||||
// Called in life() when the mob has no client.
|
||||
/datum/species/proc/handle_npc(var/mob/living/carbon/human/H)
|
||||
return
|
||||
|
||||
// Called when lying down on a water tile.
|
||||
/datum/species/proc/can_breathe_water()
|
||||
return FALSE
|
||||
@@ -193,6 +193,9 @@
|
||||
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
|
||||
)
|
||||
|
||||
/datum/species/skrell/can_breathe_water()
|
||||
return TRUE
|
||||
|
||||
/datum/species/diona
|
||||
name = "Diona"
|
||||
name_plural = "Dionaea"
|
||||
|
||||
@@ -132,8 +132,9 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
#define L_HAND_LAYER 24
|
||||
#define R_HAND_LAYER 25
|
||||
#define FIRE_LAYER 26 //If you're on fire
|
||||
#define TARGETED_LAYER 27 //BS12: Layer for the target overlay from weapon targeting system
|
||||
#define TOTAL_LAYERS 27
|
||||
#define WATER_LAYER 27 //If you're submerged in water.
|
||||
#define TARGETED_LAYER 28 //BS12: Layer for the target overlay from weapon targeting system
|
||||
#define TOTAL_LAYERS 29
|
||||
//////////////////////////////////
|
||||
|
||||
/mob/living/carbon/human
|
||||
@@ -461,6 +462,7 @@ var/global/list/damage_icon_parts = list()
|
||||
update_inv_legcuffed(0)
|
||||
update_inv_pockets(0)
|
||||
update_fire(0)
|
||||
update_water(0)
|
||||
update_surgery(0)
|
||||
UpdateDamageIcon()
|
||||
update_icons()
|
||||
@@ -1116,6 +1118,17 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_water(var/update_icons=1)
|
||||
overlays_standing[WATER_LAYER] = null
|
||||
var/depth = check_submerged()
|
||||
if(depth)
|
||||
if(!lying)
|
||||
overlays_standing[WATER_LAYER] = image("icon" = 'icons/mob/submerged.dmi', "icon_state" = "human_swimming_[depth]")
|
||||
// Lying sideways with the overlay looked strange. Another overlay will be needed in the future.
|
||||
|
||||
if(update_icons)
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/human/proc/update_surgery(var/update_icons=1)
|
||||
overlays_standing[SURGERY_LEVEL] = null
|
||||
var/image/total = new
|
||||
@@ -1151,4 +1164,5 @@ var/global/list/damage_icon_parts = list()
|
||||
#undef R_HAND_LAYER
|
||||
#undef TARGETED_LAYER
|
||||
#undef FIRE_LAYER
|
||||
#undef WATER_LAYER
|
||||
#undef TOTAL_LAYERS
|
||||
|
||||
@@ -774,6 +774,7 @@ default behaviour is:
|
||||
density = 0
|
||||
if(l_hand) unEquip(l_hand)
|
||||
if(r_hand) unEquip(r_hand)
|
||||
update_water() // Submerges the mob.
|
||||
else
|
||||
density = initial(density)
|
||||
|
||||
@@ -792,3 +793,10 @@ default behaviour is:
|
||||
update_icons()
|
||||
return canmove
|
||||
|
||||
/mob/living/proc/update_water() // Involves overlays for humans. Maybe we'll get submerged sprites for borgs in the future?
|
||||
return
|
||||
|
||||
/mob/living/proc/can_feel_pain(var/check_organ)
|
||||
if(isSynthetic())
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// This holds information about a specific 'planetside' area, such as its time, weather, etc. This will most likely be used to model Sif,
|
||||
// but away missions may also have use for this.
|
||||
|
||||
/datum/planet
|
||||
var/name = "a rock"
|
||||
var/desc = "Someone neglected to write a nice description for this poor rock."
|
||||
|
||||
var/datum/time/current_time = new() // Holds the current time for sun positioning. Note that we assume day and night is the same length because simplicity.
|
||||
var/sun_process_interval = 1 HOUR
|
||||
var/sun_last_process = null // world.time
|
||||
|
||||
var/datum/weather_holder/weather_holder
|
||||
|
||||
var/sun_position = 0 // 0 means midnight, 1 means noon.
|
||||
var/expected_z_levels = list()
|
||||
|
||||
/datum/planet/New()
|
||||
..()
|
||||
weather_holder = new(src)
|
||||
current_time = current_time.make_random_time()
|
||||
update_sun()
|
||||
|
||||
/datum/planet/proc/process(amount)
|
||||
if(current_time)
|
||||
current_time = current_time.add_seconds(amount)
|
||||
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()
|
||||
|
||||
// This changes the position of the sun on the planet.
|
||||
/datum/planet/proc/update_sun()
|
||||
sun_last_process = world.time
|
||||
|
||||
|
||||
/datum/planet/proc/update_weather()
|
||||
if(weather_holder)
|
||||
weather_holder.process()
|
||||
|
||||
// Returns the time datum of Sif.
|
||||
/proc/get_sif_time()
|
||||
if(planet_sif)
|
||||
return planet_sif.current_time
|
||||
@@ -0,0 +1,96 @@
|
||||
var/datum/planet/sif/planet_sif = null
|
||||
|
||||
/datum/planet/sif
|
||||
name = "Sif"
|
||||
|
||||
/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.
|
||||
|
||||
/datum/planet/sif/New()
|
||||
..()
|
||||
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/lerp_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 = (Interpolate(low_brightness, high_brightness, weight = lerp_weight) ) * weather_light_modifier
|
||||
|
||||
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 = Interpolate(low_r, high_r, weight = lerp_weight)
|
||||
var/new_g = Interpolate(low_g, high_g, weight = lerp_weight)
|
||||
var/new_b = Interpolate(low_b, high_b, weight = lerp_weight)
|
||||
|
||||
var/new_color = rgb(new_r, new_g, new_b)
|
||||
|
||||
var/i = 0
|
||||
for(var/turf/simulated/floor/T in outdoor_turfs)
|
||||
T.set_light(2, new_brightness, new_color)
|
||||
i++
|
||||
if(i % 30 == 0)
|
||||
sleep(1)
|
||||
@@ -0,0 +1,76 @@
|
||||
// This datum allows one to add and subtract various lengths of time. It really shines when using an alternate time system.
|
||||
|
||||
/datum/time
|
||||
// Note that the following is actually measured in 10ths of a second.
|
||||
var/seconds_in_day = 60 * 60 * 24 * 10 // 86,400 seconds
|
||||
var/seconds_in_hour = 60 * 60 * 10 // 3,600 seconds
|
||||
var/seconds_in_minute = 60 * 10
|
||||
|
||||
// This holds the amount of seconds.
|
||||
var/seconds_stored = 0
|
||||
|
||||
/datum/time/New(new_time)
|
||||
if(new_time)
|
||||
seconds_stored = new_time
|
||||
..()
|
||||
|
||||
/datum/time/proc/add_seconds(amount)
|
||||
var/answer = seconds_stored + amount * 10
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/add_minutes(amount)
|
||||
var/real_amount = amount * seconds_in_minute
|
||||
var/answer = real_amount + seconds_stored
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/add_hours(amount)
|
||||
var/real_amount = amount * seconds_in_hour
|
||||
var/answer = real_amount + seconds_stored
|
||||
if(answer >= seconds_in_day)
|
||||
rollover(answer)
|
||||
return new type(answer)
|
||||
|
||||
/datum/time/proc/rollover(time)
|
||||
return max(time - seconds_in_day, 0)
|
||||
|
||||
/datum/time/proc/make_random_time()
|
||||
return new type(rand(0, seconds_in_day - 1))
|
||||
|
||||
// This works almost exactly like time2text.
|
||||
// The advantage of this is that it can handle time systems beyond 24h.
|
||||
// The downside is a lack of date capability.
|
||||
/datum/time/proc/show_time(format)
|
||||
var/time = seconds_stored
|
||||
while(time >= seconds_in_day) // First, get rid of extra days.
|
||||
time = rollover(time)
|
||||
|
||||
var/hours = time / seconds_in_hour
|
||||
var/remaining_hour = time % seconds_in_hour
|
||||
var/minutes = remaining_hour / seconds_in_minute
|
||||
var/seconds = remaining_hour % seconds_in_minute / 10
|
||||
|
||||
|
||||
var/hour_text = num2text(Floor(hours))
|
||||
if(length(hour_text) < 2)
|
||||
hour_text = "0[hour_text]" // Add padding if needed, to look more like time2text().
|
||||
|
||||
var/minute_text = num2text(Floor(minutes))
|
||||
if(length(minute_text) < 2)
|
||||
minute_text = "0[minute_text]"
|
||||
|
||||
var/second_text = num2text(Floor(seconds))
|
||||
if(length(second_text) < 2)
|
||||
second_text = "0[second_text]"
|
||||
|
||||
var/answer = replacetext(format, "hh", hour_text)
|
||||
answer = replacetext(answer, "mm", minute_text)
|
||||
answer = replacetext(answer, "ss", second_text)
|
||||
return answer
|
||||
|
||||
// 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.
|
||||
@@ -0,0 +1,268 @@
|
||||
#define WEATHER_CLEAR "clear"
|
||||
#define WEATHER_OVERCAST "overcast"
|
||||
#define WEATHER_LIGHT_SNOW "light snow"
|
||||
#define WEATHER_SNOW "snow"
|
||||
#define WEATHER_BLIZZARD "blizzard"
|
||||
#define WEATHER_RAIN "rain"
|
||||
#define WEATHER_STORM "storm"
|
||||
#define WEATHER_HAIL "hail"
|
||||
#define WEATHER_WINDY "windy"
|
||||
#define WEATHER_HOT "hot"
|
||||
|
||||
/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/planetary_wall_type = null // Which walls to look for when updating temperature.
|
||||
|
||||
/datum/weather_holder/New(var/source)
|
||||
..()
|
||||
our_planet = source
|
||||
for(var/A in allowed_weather_types)
|
||||
var/datum/weather/W = allowed_weather_types[A]
|
||||
if(istype(W))
|
||||
W.holder = src
|
||||
|
||||
/datum/weather_holder/proc/change_weather(var/new_weather)
|
||||
var/old_light_modifier = 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.
|
||||
current_weather = allowed_weather_types[new_weather]
|
||||
next_weather_shift = world.time + rand(20, 30) MINUTES
|
||||
|
||||
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).")
|
||||
|
||||
/datum/weather_holder/proc/process()
|
||||
if(world.time >= next_weather_shift)
|
||||
var/new_weather
|
||||
if(!current_weather)
|
||||
new_weather = pickweight(roundstart_weather_chances)
|
||||
else
|
||||
new_weather = pickweight(current_weather.transition_chances)
|
||||
change_weather(new_weather)
|
||||
else
|
||||
current_weather.process_effects()
|
||||
|
||||
/datum/weather_holder/proc/update_icon_effects()
|
||||
if(current_weather)
|
||||
for(var/turf/simulated/floor/T in outdoor_turfs)
|
||||
if(T.z in our_planet.expected_z_levels)
|
||||
T.overlays -= T.weather_overlay
|
||||
T.weather_overlay = image(icon = current_weather.icon, icon_state = current_weather.icon_state, layer = LIGHTING_LAYER - 1)
|
||||
T.overlays += T.weather_overlay
|
||||
|
||||
/datum/weather_holder/proc/update_temperature()
|
||||
temperature = Interpolate(current_weather.temp_low, current_weather.temp_high, weight = our_planet.sun_position)
|
||||
|
||||
for(var/turf/unsimulated/wall/planetary/wall in planetary_walls)
|
||||
if(ispath(wall.type, planetary_wall_type))
|
||||
wall.temperature = temperature
|
||||
for(var/dir in cardinal)
|
||||
var/turf/simulated/T = get_step(wall, dir)
|
||||
if(istype(T))
|
||||
if(T.zone)
|
||||
T.zone.rebuild()
|
||||
|
||||
|
||||
/datum/weather_holder/proc/get_weather_datum(desired_type)
|
||||
return allowed_weather_types[desired_type]
|
||||
|
||||
/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()
|
||||
)
|
||||
planetary_wall_type = /turf/unsimulated/wall/planetary/sif
|
||||
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
|
||||
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/light_modifier = 1.0 // Lower numbers means more darkness.
|
||||
var/transition_chances = list() // Assoc list
|
||||
var/datum/weather_holder/holder = null
|
||||
|
||||
/datum/weather/proc/process_effects()
|
||||
return
|
||||
|
||||
/datum/weather/sif
|
||||
name = "sif base"
|
||||
temp_high = 243.15 // -20c
|
||||
temp_low = 233.15 // -30c
|
||||
|
||||
/datum/weather/sif/clear
|
||||
name = "clear"
|
||||
transition_chances = list(
|
||||
WEATHER_CLEAR = 60,
|
||||
WEATHER_OVERCAST = 40
|
||||
)
|
||||
|
||||
/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
|
||||
)
|
||||
|
||||
/datum/weather/sif/light_snow
|
||||
name = "light snow"
|
||||
icon_state = "snowfall_light"
|
||||
temp_high = 238.15 // -25c
|
||||
temp_low = 228.15 // -35c
|
||||
light_modifier = 0.7
|
||||
transition_chances = list(
|
||||
WEATHER_OVERCAST = 20,
|
||||
WEATHER_LIGHT_SNOW = 50,
|
||||
WEATHER_SNOW = 25,
|
||||
WEATHER_HAIL = 5
|
||||
)
|
||||
|
||||
/datum/weather/sif/snow
|
||||
name = "moderate snow"
|
||||
icon_state = "snowfall_med"
|
||||
temp_high = 233.15 // -30c
|
||||
temp_low = 223.15 // -40c
|
||||
light_modifier = 0.5
|
||||
transition_chances = list(
|
||||
WEATHER_LIGHT_SNOW = 20,
|
||||
WEATHER_SNOW = 50,
|
||||
WEATHER_BLIZZARD = 20,
|
||||
WEATHER_HAIL = 5,
|
||||
WEATHER_OVERCAST = 5
|
||||
)
|
||||
|
||||
/datum/weather/sif/snow/process_effects()
|
||||
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
|
||||
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 = 223.15 // -40c
|
||||
temp_low = 203.15 // -60c
|
||||
light_modifier = 0.3
|
||||
transition_chances = list(
|
||||
WEATHER_SNOW = 45,
|
||||
WEATHER_BLIZZARD = 40,
|
||||
WEATHER_HAIL = 10,
|
||||
WEATHER_OVERCAST = 5
|
||||
)
|
||||
|
||||
/datum/weather/sif/blizzard/process_effects()
|
||||
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
|
||||
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"
|
||||
light_modifier = 0.5
|
||||
transition_chances = list(
|
||||
WEATHER_OVERCAST = 25,
|
||||
WEATHER_LIGHT_SNOW = 10,
|
||||
WEATHER_RAIN = 50,
|
||||
WEATHER_STORM = 10,
|
||||
WEATHER_HAIL = 5
|
||||
)
|
||||
|
||||
/datum/weather/sif/rain/process_effects()
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(L.z in holder.our_planet.expected_z_levels)
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T.outdoors)
|
||||
return // They're indoors, so no need to rain on them.
|
||||
|
||||
L.adjust_fire_stacks(-5)
|
||||
to_chat(L, "<span class='warning'>Rain falls on you.</span>")
|
||||
|
||||
/datum/weather/sif/storm
|
||||
name = "storm"
|
||||
icon_state = "storm"
|
||||
temp_high = 233.15 // -30c
|
||||
temp_low = 213.15 // -50c
|
||||
light_modifier = 0.3
|
||||
transition_chances = list(
|
||||
WEATHER_RAIN = 45,
|
||||
WEATHER_STORM = 40,
|
||||
WEATHER_HAIL = 10,
|
||||
WEATHER_OVERCAST = 5
|
||||
)
|
||||
|
||||
/datum/weather/sif/rain/process_effects()
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(L.z in holder.our_planet.expected_z_levels)
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T.outdoors)
|
||||
return // They're indoors, so no need to rain on them.
|
||||
|
||||
L.adjust_fire_stacks(-10)
|
||||
to_chat(L, "<span class='warning'>Rain falls on you, drenching you in water.</span>")
|
||||
|
||||
/datum/weather/sif/hail
|
||||
name = "hail"
|
||||
icon_state = "hail"
|
||||
temp_high = 233.15 // -30c
|
||||
temp_low = 213.15 // -50c
|
||||
light_modifier = 0.3
|
||||
transition_chances = list(
|
||||
WEATHER_RAIN = 45,
|
||||
WEATHER_STORM = 10,
|
||||
WEATHER_HAIL = 40,
|
||||
WEATHER_OVERCAST = 5
|
||||
)
|
||||
|
||||
/datum/weather/sif/hail/process_effects()
|
||||
for(var/mob/living/L in living_mob_list)
|
||||
if(L.z in holder.our_planet.expected_z_levels)
|
||||
var/turf/T = get_turf(L)
|
||||
if(!T.outdoors)
|
||||
return // They're indoors, so no need to pelt them with ice.
|
||||
|
||||
var/target_zone = pick(BP_ALL)
|
||||
var/amount_blocked = L.run_armor_check(target_zone, "melee")
|
||||
|
||||
if(amount_blocked >= 100)
|
||||
return // No need to apply damage.
|
||||
|
||||
L.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, used_weapon = "hail")
|
||||
to_chat(L, "<span class='warning'>The hail raining down on you [L.can_feel_pain() ? "hurts" : "damages you"]!</span>")
|
||||
Reference in New Issue
Block a user