diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 58e2be31b01..3ad2900bfa1 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -7,23 +7,35 @@ #define PLANE_SPACE_PARALLAX -90 #define GAME_PLANE 0 + #define SPACE_LAYER 1.8 //#define TURF_LAYER 2 //For easy recordkeeping; this is a byond define #define MID_TURF_LAYER 2.02 #define HIGH_TURF_LAYER 2.03 +#define TURF_PLATING_DECAL_LAYER 2.031 +#define TURF_DECAL_LAYER 2.039 //Makes turf decals appear in DM how they will look inworld. #define ABOVE_OPEN_TURF_LAYER 2.04 #define CLOSED_TURF_LAYER 2.05 +#define BULLET_HOLE_LAYER 2.06 #define ABOVE_NORMAL_TURF_LAYER 2.08 #define LATTICE_LAYER 2.2 #define DISPOSAL_PIPE_LAYER 2.3 -#define GAS_PIPE_LAYER 2.35 +#define GAS_PIPE_HIDDEN_LAYER 2.35 #define WIRE_LAYER 2.4 #define WIRE_TERMINAL_LAYER 2.45 +#define GAS_SCRUBBER_LAYER 2.46 +#define GAS_PIPE_VISIBLE_LAYER 2.47 +#define GAS_FILTER_LAYER 2.48 +#define GAS_PUMP_LAYER 2.49 #define LOW_OBJ_LAYER 2.5 +#define LOW_SIGIL_LAYER 2.52 +#define SIGIL_LAYER 2.54 +#define HIGH_SIGIL_LAYER 2.56 #define BELOW_OPEN_DOOR_LAYER 2.6 #define BLASTDOOR_LAYER 2.65 #define OPEN_DOOR_LAYER 2.7 +#define DOOR_HELPER_LAYER 2.71 //keep this above OPEN_DOOR_LAYER #define PROJECTILE_HIT_THRESHHOLD_LAYER 2.75 //projectiles won't hit objects at or below this layer if possible #define TABLE_LAYER 2.8 #define BELOW_OBJ_LAYER 2.9 @@ -52,9 +64,13 @@ #define SPACEVINE_LAYER 4.8 #define SPACEVINE_MOB_LAYER 4.9 //#define FLY_LAYER 5 //For easy recordkeeping; this is a byond define +#define GASFIRE_LAYER 5.05 #define RIPPLE_LAYER 5.1 #define GHOST_LAYER 6 +#define LOW_LANDMARK_LAYER 9 +#define MID_LANDMARK_LAYER 9.1 +#define HIGH_LANDMARK_LAYER 9.2 #define AREA_LAYER 10 #define MASSIVE_OBJ_LAYER 11 #define POINT_LAYER 12 @@ -62,6 +78,26 @@ #define LIGHTING_PLANE 15 #define LIGHTING_LAYER 15 +#define ABOVE_LIGHTING_PLANE 16 +#define ABOVE_LIGHTING_LAYER 16 + +#define BYOND_LIGHTING_PLANE 17 +#define BYOND_LIGHTING_LAYER 17 + //HUD layer defines + +#define FULLSCREEN_PLANE 18 +#define FLASH_LAYER 18 +#define FULLSCREEN_LAYER 18.1 +#define UI_DAMAGE_LAYER 18.2 +#define BLIND_LAYER 18.3 +#define CRIT_LAYER 18.4 +#define CURSE_LAYER 18.5 + +#define HUD_PLANE 19 #define HUD_LAYER 19 -#define HUD_PLANE 90 \ No newline at end of file +#define ABOVE_HUD_PLANE 20 +#define ABOVE_HUD_LAYER 20 + +#define SPLASHSCREEN_LAYER 21 +#define SPLASHSCREEN_PLANE 21 \ No newline at end of file diff --git a/code/controllers/Processes/nanoui.dm b/code/controllers/Processes/nanoui.dm deleted file mode 100644 index 1667af943da..00000000000 --- a/code/controllers/Processes/nanoui.dm +++ /dev/null @@ -1,19 +0,0 @@ -/datum/controller/process/nanoui/setup() - name = "nanoui" - schedule_interval = 20 // every 2 seconds - -/datum/controller/process/nanoui/statProcess() - ..() - stat(null, "[nanomanager.processing_uis.len] UIs") - -/datum/controller/process/nanoui/doWork() - for(last_object in nanomanager.processing_uis) - var/datum/nanoui/NUI = last_object - if(istype(NUI) && isnull(NUI.gcDestroyed)) - try - NUI.process() - catch(var/exception/e) - catchException(e, NUI) - else - catchBadType(NUI) - nanomanager.processing_uis -= NUI diff --git a/code/controllers/Processes/weather.dm b/code/controllers/Processes/weather.dm deleted file mode 100644 index 919352313c6..00000000000 --- a/code/controllers/Processes/weather.dm +++ /dev/null @@ -1,54 +0,0 @@ -//Used for all kinds of weather, ex. lavaland ash storms. -// TODO: This could probably be better-integrated with the space manager -var/global/datum/controller/process/weather/weather_master - -/datum/controller/process/weather - var/list/processing_weather = list() - var/list/existing_weather = list() - var/list/eligible_zlevels = list() - -/datum/controller/process/weather/setup() - name = "weather" - schedule_interval = 10 - - for(var/V in subtypesof(/datum/weather)) - var/datum/weather/W = V - existing_weather |= new W - -/datum/controller/process/weather/statProcess() - ..() - stat(null, "[processing_weather.len] weather") - -/datum/controller/process/weather/doWork() - for(var/V in processing_weather) - var/datum/weather/W = V - if(W.aesthetic) - continue - for(var/mob/living/L in mob_list) - if(W.can_impact(L)) - W.impact(L) - SCHECK - 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(CALLBACK(src, .proc/make_z_eligible, Z), rand(3000, 6000) + W.weather_duration_upper, TIMER_UNIQUE) //Around 5-10 minutes between weathers - -DECLARE_GLOBAL_CONTROLLER(weather, weather_master) - -/datum/controller/process/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() - SCHECK - -/datum/controller/process/weather/proc/make_z_eligible(zlevel) - eligible_zlevels |= zlevel diff --git a/code/controllers/subsystem/weather.dm b/code/controllers/subsystem/weather.dm new file mode 100644 index 00000000000..4f5798e4ae4 --- /dev/null +++ b/code/controllers/subsystem/weather.dm @@ -0,0 +1,83 @@ +#define STARTUP_STAGE 1 +#define MAIN_STAGE 2 +#define WIND_DOWN_STAGE 3 +#define END_STAGE 4 + +//Used for all kinds of weather, ex. lavaland ash storms. +SUBSYSTEM_DEF(weather) + name = "Weather" + flags = SS_BACKGROUND + wait = 10 + runlevels = RUNLEVEL_GAME + var/list/processing = list() + var/list/eligible_zlevels = list() + var/list/next_hit_by_zlevel = list() //Used by barometers to know when the next storm is coming + +/datum/controller/subsystem/weather/fire() + // process active weather + for(var/V in processing) + var/datum/weather/W = V + if(W.aesthetic || W.stage != MAIN_STAGE) + continue + for(var/i in living_mob_list) + var/mob/living/L = i + if(W.can_weather_act(L)) + W.weather_act(L) + + // start random weather on relevant levels + for(var/z in eligible_zlevels) + var/possible_weather = eligible_zlevels[z] + var/datum/weather/W = pickweight(possible_weather) + run_weather(W, list(text2num(z))) + eligible_zlevels -= z + var/randTime = rand(3000, 6000) + addtimer(CALLBACK(src, .proc/make_eligible, z, possible_weather), randTime + initial(W.weather_duration_upper), TIMER_UNIQUE) //Around 5-10 minutes between weathers + next_hit_by_zlevel["[z]"] = world.time + randTime + initial(W.telegraph_duration) + +/datum/controller/subsystem/weather/Initialize(start_timeofday) + for(var/V in subtypesof(/datum/weather)) + var/datum/weather/W = V + var/probability = initial(W.probability) + var/target_trait = initial(W.target_trait) + + // any weather with a probability set may occur at random + if(probability) + for(var/z in levels_by_trait(target_trait)) + LAZYINITLIST(eligible_zlevels["[z]"]) + eligible_zlevels["[z]"][W] = probability + ..() + +/datum/controller/subsystem/weather/proc/run_weather(datum/weather/weather_datum_type, z_levels) + if(istext(weather_datum_type)) + for(var/V in subtypesof(/datum/weather)) + var/datum/weather/W = V + if(initial(W.name) == weather_datum_type) + weather_datum_type = V + break + if(!ispath(weather_datum_type, /datum/weather)) + CRASH("run_weather called with invalid weather_datum_type: [weather_datum_type || "null"]") + return + + if(isnull(z_levels)) + z_levels = levels_by_trait(initial(weather_datum_type.target_trait)) + else if(isnum(z_levels)) + z_levels = list(z_levels) + else if(!islist(z_levels)) + CRASH("run_weather called with invalid z_levels: [z_levels || "null"]") + return + + var/datum/weather/W = new weather_datum_type(z_levels) + W.telegraph() + +/datum/controller/subsystem/weather/proc/make_eligible(z, possible_weather) + eligible_zlevels[z] = possible_weather + next_hit_by_zlevel["[z]"] = null + +/datum/controller/subsystem/weather/proc/get_weather(z, area/active_area) + var/datum/weather/A + for(var/V in processing) + var/datum/weather/W = V + if((z in W.impacted_z_levels) && W.area_type == active_area.type) + A = W + break + return A \ No newline at end of file diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm index 3315cafb399..4e9380e2fed 100644 --- a/code/controllers/verbs.dm +++ b/code/controllers/verbs.dm @@ -94,7 +94,7 @@ debug_variables(SStimer) feedback_add_details("admin_verb","DTimer") if("Weather") - debug_variables(weather_master) + debug_variables(SSweather) feedback_add_details("admin_verb","DWeather") if("Space") debug_variables(space_manager) diff --git a/code/datums/looping_sounds/weather.dm b/code/datums/looping_sounds/weather.dm new file mode 100644 index 00000000000..d355bc59c14 --- /dev/null +++ b/code/datums/looping_sounds/weather.dm @@ -0,0 +1,47 @@ +/datum/looping_sound/active_outside_ashstorm + mid_sounds = list( + 'sound/weather/ashstorm/outside/active_mid1.ogg' = 1, + 'sound/weather/ashstorm/outside/active_mid1.ogg' = 1, + 'sound/weather/ashstorm/outside/active_mid1.ogg' = 1 + ) + mid_length = 80 + start_sound = 'sound/weather/ashstorm/outside/active_start.ogg' + start_length = 130 + end_sound = 'sound/weather/ashstorm/outside/active_end.ogg' + volume = 80 + +/datum/looping_sound/active_inside_ashstorm + mid_sounds = list( + 'sound/weather/ashstorm/inside/active_mid1.ogg' = 1, + 'sound/weather/ashstorm/inside/active_mid2.ogg' = 1, + 'sound/weather/ashstorm/inside/active_mid3.ogg' = 1 + ) + mid_length = 80 + start_sound = 'sound/weather/ashstorm/inside/active_start.ogg' + start_length = 130 + end_sound = 'sound/weather/ashstorm/inside/active_end.ogg' + volume = 60 + +/datum/looping_sound/weak_outside_ashstorm + mid_sounds = list( + 'sound/weather/ashstorm/outside/weak_mid1.ogg' = 1, + 'sound/weather/ashstorm/outside/weak_mid2.ogg' = 1, + 'sound/weather/ashstorm/outside/weak_mid3.ogg' = 1 + ) + mid_length = 80 + start_sound = 'sound/weather/ashstorm/outside/weak_start.ogg' + start_length = 130 + end_sound = 'sound/weather/ashstorm/outside/weak_end.ogg' + volume = 50 + +/datum/looping_sound/weak_inside_ashstorm + mid_sounds = list( + 'sound/weather/ashstorm/inside/weak_mid1.ogg' = 1, + 'sound/weather/ashstorm/inside/weak_mid2.ogg' = 1, + 'sound/weather/ashstorm/inside/weak_mid3.ogg' = 1 + ) + mid_length = 80 + start_sound = 'sound/weather/ashstorm/inside/weak_start.ogg' + start_length = 130 + end_sound = 'sound/weather/ashstorm/inside/weak_end.ogg' + volume = 30 diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index 320cc137806..7ee152648c2 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -1,10 +1,5 @@ //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." @@ -29,24 +24,25 @@ 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 = MAIN_STATION //The z-level to affect 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 = 10 //Since it's above everything else, this is the layer used by default. 2 is below mobs and walls if you need to use that. + 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 + // 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 = STATION_LEVEL // The z-level trait to affect when run randomly or when not overridden. -/datum/weather/New() + var/barometer_predictable = FALSE + var/next_hit_time = 0 //For barometers to know when the next storm will hit + +/datum/weather/New(z_levels) ..() - weather_master.existing_weather |= src - -/datum/weather/Destroy() - weather_master.existing_weather -= src - return ..() + impacted_z_levels = z_levels /datum/weather/proc/telegraph() if(stage == STARTUP_STAGE) @@ -59,17 +55,18 @@ affectareas -= get_areas(V) for(var/V in affectareas) var/area/A = V - if(is_on_level_name(A,target_z)) + if(A.z in impacted_z_levels) impacted_areas |= A weather_duration = rand(weather_duration_lower, weather_duration_upper) + START_PROCESSING(SSweather, src) update_areas() - for(var/V in player_list) - var/mob/M = V - if(is_on_level_name(M,target_z)) + for(var/M in 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) - M << sound(telegraph_sound) + SEND_SOUND(M, sound(telegraph_sound)) addtimer(CALLBACK(src, .proc/start), telegraph_duration) /datum/weather/proc/start() @@ -77,14 +74,13 @@ return stage = MAIN_STAGE update_areas() - for(var/V in player_list) - var/mob/M = V - if(is_on_level_name(M,target_z)) + for(var/M in 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) - M << sound(weather_sound) - weather_master.processing_weather |= src + SEND_SOUND(M, sound(weather_sound)) addtimer(CALLBACK(src, .proc/wind_down), weather_duration) /datum/weather/proc/wind_down() @@ -92,24 +88,25 @@ return stage = WIND_DOWN_STAGE update_areas() - for(var/V in player_list) - var/mob/M = V - if(is_on_level_name(M,target_z)) + for(var/M in 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) - M << sound(end_sound) - weather_master.processing_weather -= src + SEND_SOUND(M, sound(end_sound)) addtimer(CALLBACK(src, .proc/end), end_duration) /datum/weather/proc/end() if(stage == END_STAGE) - return + return 1 stage = END_STAGE + STOP_PROCESSING(SSweather, src) update_areas() -/datum/weather/proc/can_impact(mob/living/L) //Can this weather impact a mob? - if(!is_on_level_name(L,target_z)) +/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 @@ -117,7 +114,7 @@ return return 1 -/datum/weather/proc/impact(mob/living/L) //What effect does this weather have on the hapless mob? +/datum/weather/proc/weather_act(mob/living/L) //What effect does this weather have on the hapless mob? return /datum/weather/proc/update_areas() @@ -136,8 +133,8 @@ N.icon_state = end_overlay if(END_STAGE) N.color = null - N.icon_state = initial(N.icon_state) + N.icon_state = "" N.icon = 'icons/turf/areas.dmi' - N.layer = 10 //Just default back to normal area stuff since I assume setting a var is faster than initial + 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 + N.set_opacity(FALSE) diff --git a/code/datums/weather/weather_types.dm b/code/datums/weather/weather_types.dm deleted file mode 100644 index 1581938bd96..00000000000 --- a/code/datums/weather/weather_types.dm +++ /dev/null @@ -1,118 +0,0 @@ -//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 = "Waves of heat emanate from the ground..." - telegraph_duration = 150 - - weather_message = "The floor is lava! Get on top of something!" - weather_duration_lower = 300 - weather_duration_upper = 600 - weather_overlay = "lava" - - end_message = "The ground cools and returns to its usual form." - end_duration = 0 - - area_type = /area - target_z = MAIN_STATION - - overlay_layer = 2 //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/floor_is_lava/fake - name = "fake lava" - aesthetic = TRUE - -/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 = "The lights begin to dim... is the power going out?" - telegraph_duration = 150 - - weather_message = "This isn't your everyday darkness... this is advanced darkness!" - weather_duration_lower = 300 - weather_duration_upper = 300 - - end_message = "At last, the darkness recedes." - end_duration = 0 - - area_type = /area - target_z = MAIN_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 = "An eerie moan rises on the wind. Sheets of burning ash blacken the horizon. Seek shelter." - telegraph_duration = 300 - telegraph_sound = 'sound/lavaland/ash_storm_windup.ogg' - telegraph_overlay = "light_ash" - - weather_message = "Smoldering clouds of scorching ash billow down around you! Get inside!" - weather_duration_lower = 600 - weather_duration_upper = 1500 - weather_sound = 'sound/lavaland/ash_storm_start.ogg' - weather_overlay = "ash_storm" - - end_message = "The shrieking wind whips away the last of the ash falls to its usual murmur. It should be safe to go outside now." - end_duration = 300 - end_sound = 'sound/lavaland/ash_storm_end.ogg' - end_overlay = "light_ash" - - area_type = /area/mine/dangerous - target_z = MINING - - 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 = "Gentle embers waft down around you like grotesque snow. The storm seems to have passed you by..." - weather_sound = 'sound/lavaland/ash_storm_windup.ogg' - weather_overlay = "light_ash" - - end_message = "The emberfall slows, stops. Another layer of hardened soot to the basalt beneath your feet." - - aesthetic = TRUE - - probability = 10 diff --git a/code/datums/weather/weather_types/ash_storm.dm b/code/datums/weather/weather_types/ash_storm.dm new file mode 100644 index 00000000000..3f4c57c4196 --- /dev/null +++ b/code/datums/weather/weather_types/ash_storm.dm @@ -0,0 +1,108 @@ +//Ash storms happen frequently on lavaland. They heavily obscure vision, and cause high fire damage to anyone caught outside. +/datum/weather/ash_storm + 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 = "An eerie moan rises on the wind. Sheets of burning ash blacken the horizon. Seek shelter." + telegraph_duration = 300 + telegraph_overlay = "light_ash" + + weather_message = "Smoldering clouds of scorching ash billow down around you! Get inside!" + weather_duration_lower = 600 + weather_duration_upper = 1200 + weather_overlay = "ash_storm" + + end_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." + end_duration = 300 + end_overlay = "light_ash" + + area_type = /area/mine/dangerous // /area/lavaland/surface/outdoors + target_trait = ORE_LEVEL + + immunity_type = "ash" + +// probability = 90 + + barometer_predictable = TRUE + + var/datum/looping_sound/active_outside_ashstorm/sound_ao = new(list(), FALSE, TRUE) + var/datum/looping_sound/active_inside_ashstorm/sound_ai = new(list(), FALSE, TRUE) + var/datum/looping_sound/weak_outside_ashstorm/sound_wo = new(list(), FALSE, TRUE) + var/datum/looping_sound/weak_inside_ashstorm/sound_wi = new(list(), FALSE, TRUE) + +/datum/weather/ash_storm/telegraph() + . = ..() + var/list/inside_areas = list() + var/list/outside_areas = list() + var/list/eligible_areas = list() + for(var/z in impacted_z_levels) + eligible_areas += space_manager.areas_in_z["[z]"] + for(var/i in 1 to eligible_areas.len) + var/area/place = eligible_areas[i] + if(place.outdoors) + outside_areas += place + else + inside_areas += place + CHECK_TICK + + sound_ao.output_atoms = outside_areas + sound_ai.output_atoms = inside_areas + sound_wo.output_atoms = outside_areas + sound_wi.output_atoms = inside_areas + + sound_wo.start() + sound_wi.start() + +/datum/weather/ash_storm/start() + . = ..() + sound_wo.stop() + sound_wi.stop() + + sound_ao.start() + sound_ai.start() + +/datum/weather/ash_storm/wind_down() + . = ..() + sound_ao.stop() + sound_ai.stop() + + sound_wo.start() + sound_wi.start() + +/datum/weather/ash_storm/end() + . = ..() + sound_wo.stop() + sound_wi.stop() + +/datum/weather/ash_storm/proc/is_ash_immune(atom/L) + while(L && !isturf(L)) + if(ismecha(L)) //Mechs are immune + return TRUE + if(ishuman(L)) //Are you immune? + var/mob/living/carbon/human/H = L + var/thermal_protection = H.get_thermal_protection() + if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT) + return TRUE + L = L.loc //Matryoshka check + return FALSE //RIP you + +/datum/weather/ash_storm/weather_act(mob/living/L) + if(is_ash_immune(L)) + return + L.adjustFireLoss(4) + + +//Emberfalls are the result of an ash storm passing by close to the playable area of lavaland. They have a 10% chance to trigger in place of an ash storm. +/datum/weather/ash_storm/emberfall + name = "emberfall" + desc = "A passing ash storm blankets the area in harmless embers." + + weather_message = "Gentle embers waft down around you like grotesque snow. The storm seems to have passed you by..." + weather_overlay = "light_ash" + + end_message = "The emberfall slows, stops. Another layer of hardened soot to the basalt beneath your feet." + end_sound = null + + aesthetic = TRUE + +// probability = 10 \ No newline at end of file diff --git a/code/datums/weather/weather_types/floor_is_lava.dm b/code/datums/weather/weather_types/floor_is_lava.dm new file mode 100644 index 00000000000..fe7391ec9f0 --- /dev/null +++ b/code/datums/weather/weather_types/floor_is_lava.dm @@ -0,0 +1,39 @@ +//Causes fire damage to anyone not standing on a dense object. +/datum/weather/floor_is_lava + name = "the floor is lava" + desc = "The ground turns into surprisingly cool lava, lightly damaging anything on the floor." + + telegraph_message = "You feel the ground beneath you getting hot. Waves of heat distort the air." + telegraph_duration = 150 + + weather_message = "The floor is lava! Get on top of something!" + weather_duration_lower = 300 + weather_duration_upper = 600 + weather_overlay = "lava" + + end_message = "The ground cools and returns to its usual form." + end_duration = 0 + + area_type = /area + protected_areas = list(/area/space) + target_trait = STATION_LEVEL + + overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only + immunity_type = "lava" + + +/datum/weather/floor_is_lava/weather_act(mob/living/L) + if(issilicon(L)) + return + for(var/obj/structure/O in L.loc) + if(O.density || O.buckled_mob && istype(O, /obj/structure/stool/bed)) + return + if(L.loc.density) + return + if(!L.client) //Only sentient people are going along with it! + return + L.adjustFireLoss(3) + +/datum/weather/floor_is_lava/fake + name = "the floor is lava (fake)" + aesthetic = TRUE \ No newline at end of file diff --git a/code/datums/weather/weather_types/radiation_storm.dm b/code/datums/weather/weather_types/radiation_storm.dm new file mode 100644 index 00000000000..acd155e7560 --- /dev/null +++ b/code/datums/weather/weather_types/radiation_storm.dm @@ -0,0 +1,61 @@ +//Radiation storms occur when the station passes through an irradiated area, and irradiate anyone not standing in protected areas (maintenance, emergency storage, etc.) +/datum/weather/rad_storm + name = "radiation storm" + desc = "A cloud of intense radiation passes through the area dealing rad damage to those who are unprotected." + + telegraph_duration = 400 + telegraph_message = "The air begins to grow warm." + + weather_message = "You feel waves of heat wash over you! Find shelter!" + weather_overlay = "ash_storm" + weather_duration_lower = 600 + weather_duration_upper = 1500 + weather_color = "green" + weather_sound = 'sound/misc/bloblarm.ogg' + + end_duration = 100 + end_message = "The air seems to be cooling off again." + + area_type = /area + protected_areas = list(/area/maintenance, /area/turret_protected/ai_upload, /area/turret_protected/ai_upload_foyer, + /area/turret_protected/ai, /area/storage/emergency, /area/storage/emergency2, /area/crew_quarters/sleep, /area/security/brig, /area/shuttle) + target_trait = STATION_LEVEL + + immunity_type = "rad" + +/datum/weather/rad_storm/telegraph() + ..() + status_alarm(TRUE) + make_maint_all_access() + + +/datum/weather/rad_storm/weather_act(mob/living/L) + var/resist = L.getarmor(null, "rad") + if(prob(40)) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(!(RADIMMUNE in H.species.species_traits)) + if(prob(max(0, 100 - resist))) + randmuti(H) // Applies bad mutation + if(prob(50)) + if(prob(90)) + randmutb(H) + else + randmutg(H) + domutcheck(H, null, 1) + + L.apply_effect(20, IRRADIATE, resist) + +/datum/weather/rad_storm/end() + if(..()) + return + priority_announcement.Announce("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert") + status_alarm(FALSE) + revoke_maint_all_access() + +/datum/weather/rad_storm/proc/status_alarm(active) //Makes the status displays show the radiation warning for those who missed the announcement. + if(active) + post_status("alert", "radiation") + else + post_status("blank") + post_status("shuttle") \ No newline at end of file diff --git a/code/datums/weather/weather_types/snow_storm.dm b/code/datums/weather/weather_types/snow_storm.dm new file mode 100644 index 00000000000..39ad0e8fa5d --- /dev/null +++ b/code/datums/weather/weather_types/snow_storm.dm @@ -0,0 +1,28 @@ +/datum/weather/snow_storm + name = "snow storm" + desc = "Harsh snowstorms roam the topside of this arctic planet, burying any area unfortunate enough to be in its path." + probability = 90 + + telegraph_message = "Drifting particles of snow begin to dust the surrounding area.." + telegraph_duration = 300 + telegraph_overlay = "light_snow" + + weather_message = "Harsh winds pick up as dense snow begins to fall from the sky! Seek shelter!" + weather_overlay = "snow_storm" + weather_duration_lower = 600 + weather_duration_upper = 1500 + + end_duration = 100 + end_message = "The snowfall dies down, it should be safe to go outside again." + +// area_type = /area/awaymission/snowdin/outside + target_trait = AWAY_LEVEL + + immunity_type = "snow" + + barometer_predictable = TRUE + + +/datum/weather/snow_storm/weather_act(mob/living/L) + L.adjust_bodytemperature(-rand(5, 15)) + diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm index 90b45a19170..e331376a0dc 100644 --- a/code/game/area/Space Station 13 areas.dm +++ b/code/game/area/Space Station 13 areas.dm @@ -20,13 +20,12 @@ NOTE: there are two lists of areas in the end of this file: centcom and station var/atmosalm = ATMOS_ALARM_NONE var/poweralm = 1 var/party = null - var/radalert = 0 var/report_alerts = 1 // Should atmos alerts notify the AI/computers level = null name = "Space" icon = 'icons/turf/areas.dmi' icon_state = "unknown" - layer = 10 + layer = AREA_LAYER luminosity = 0 mouse_opacity = 0 invisibility = INVISIBILITY_LIGHTING @@ -141,9 +140,6 @@ var/list/ghostteleportlocs = list() /area/space/readyalert() return -/area/space/radiation_alert() - return - /area/space/partyalert() return diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 8a9a108c7b3..44a9ae7e522 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -22,7 +22,7 @@ ..() icon_state = "" - layer = 10 + layer = AREA_LAYER uid = ++global_uid all_areas += src map_name = name // Save the initial (the name set in the map) name of the area. @@ -45,7 +45,24 @@ blend_mode = BLEND_MULTIPLY // Putting this in the constructor so that it stops the icons being screwed up in the map editor. /area/Initialize() - ..() + . = ..() + + if(contents.len) + var/list/areas_in_z = space_manager.areas_in_z + var/z + for(var/i in 1 to contents.len) + var/atom/thing = contents[i] + if(!thing) + continue + z = thing.z + break + if(!z) + WARNING("No z found for [src]") + return + if(!areas_in_z["[z]"]) + areas_in_z["[z]"] = list() + areas_in_z["[z]"] += src + return INITIALIZE_HINT_LATELOAD /area/LateInitialize() @@ -160,16 +177,6 @@ eject = 0 updateicon() -/area/proc/radiation_alert() - if(!radalert) - radalert = 1 - updateicon() - -/area/proc/reset_radiation_alert() - if(radalert) - radalert = 0 - updateicon() - /area/proc/partyalert() if(!party) party = 1 @@ -183,11 +190,8 @@ updateicon() /area/proc/updateicon() - if(radalert) // always show the radiation alert, regardless of power - icon_state = "radiation" - invisibility = INVISIBILITY_LIGHTING - else if((fire || eject || party) && (!requires_power||power_environ))//If it doesn't require power, can still activate this proc. - if(fire && !radalert && !eject && !party) + if((fire || eject || party) && (!requires_power||power_environ))//If it doesn't require power, can still activate this proc. + if(fire && !eject && !party) icon_state = "red" else if(!fire && eject && !party) icon_state = "red" @@ -197,9 +201,15 @@ icon_state = "blue-red" invisibility = INVISIBILITY_LIGHTING else - // new lighting behaviour with obj lights - icon_state = null - invisibility = INVISIBILITY_MAXIMUM + var/weather_icon + for(var/V in SSweather.processing) + var/datum/weather/W = V + if(W.stage != END_STAGE && (src in W.impacted_areas)) + W.update_areas() + weather_icon = TRUE + if(!weather_icon) + icon_state = null + invisibility = INVISIBILITY_MAXIMUM /area/space/updateicon() icon_state = null @@ -384,4 +394,4 @@ for(var/obj/machinery/door/airlock/temp_airlock in src) temp_airlock.prison_open() for(var/obj/machinery/door/window/temp_windoor in src) - temp_windoor.open() + temp_windoor.open() \ No newline at end of file diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index fa582362308..054d4d441a3 100644 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -528,7 +528,8 @@ if("alert") status_signal.data["picture_state"] = data1 - frequency.post_signal(src, status_signal) + spawn(0) + frequency.post_signal(src, status_signal) /obj/machinery/computer/communications/Destroy() diff --git a/code/game/machinery/computer/pod.dm b/code/game/machinery/computer/pod.dm index 98d14c8ac30..4cbf105c100 100644 --- a/code/game/machinery/computer/pod.dm +++ b/code/game/machinery/computer/pod.dm @@ -205,8 +205,8 @@ if(href_list["dstele"]) var/choices = list(0) var/list/reachable_levels = levels_by_trait(REACHABLE) - for(var/datum/space_level/S in reachable_levels) - choices += S.zpos + for(var/z in reachable_levels) + choices += z var/obj/machinery/computer/pod/deathsquad/D = src var/input = input("Enter the destination Z-Level. The mechs will arrive from the East. Leave 0 if you don't want to set a specific ZLevel", "Mass Driver Controls", 0) in choices D.teleporter_dest = input diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 2a8e155dd06..9912957c2bb 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -313,6 +313,9 @@ REAGENT SCANNER throw_range = 7 materials = list(MAT_METAL=30, MAT_GLASS=20) origin_tech = "magnets=1;engineering=1" + var/cooldown = FALSE + var/cooldown_time = 250 + var/accuracy // 0 is the best accuracy. /obj/item/analyzer/attack_self(mob/user as mob) @@ -366,6 +369,69 @@ REAGENT SCANNER src.add_fingerprint(user) return +/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens + ..() + + if(!user.incapacitated() && Adjacent(user)) + + if(cooldown) + to_chat(user, "[src]'s barometer function is prepraring itself.") + return + + var/turf/T = get_turf(user) + if(!T) + return + + playsound(src, 'sound/effects/pop.ogg', 100) + var/area/user_area = T.loc + var/datum/weather/ongoing_weather = null + + if(!user_area.outdoors) + to_chat(user, "[src]'s barometer function won't work indoors!") + return + + for(var/V in SSweather.processing) + var/datum/weather/W = V + if(W.barometer_predictable && (T.z in W.impacted_z_levels) && W.area_type == user_area.type && !(W.stage == END_STAGE)) + ongoing_weather = W + break + + if(ongoing_weather) + if((ongoing_weather.stage == MAIN_STAGE) || (ongoing_weather.stage == WIND_DOWN_STAGE)) + to_chat(user, "[src]'s barometer function can't trace anything while the storm is [ongoing_weather.stage == MAIN_STAGE ? "already here!" : "winding down."]") + return + + to_chat(user, "The next [ongoing_weather] will hit in [butchertime(ongoing_weather.next_hit_time - world.time)].") + if(ongoing_weather.aesthetic) + to_chat(user, "[src]'s barometer function says that the next storm will breeze on by.") + else + var/next_hit = SSweather.next_hit_by_zlevel["[T.z]"] + var/fixed = next_hit ? next_hit - world.time : -1 + if(fixed < 0) + to_chat(user, "[src]'s barometer function was unable to trace any weather patterns.") + else + to_chat(user, "[src]'s barometer function says a storm will land in approximately [butchertime(fixed)].") + cooldown = TRUE + addtimer(CALLBACK(src,/obj/item/analyzer/proc/ping), cooldown_time) + +/obj/item/analyzer/proc/ping() + if(isliving(loc)) + var/mob/living/L = loc + to_chat(L, "[src]'s barometer function is ready!") + playsound(src, 'sound/machines/click.ogg', 100) + cooldown = FALSE + +/obj/item/analyzer/proc/butchertime(amount) + if(!amount) + return + if(accuracy) + var/inaccurate = round(accuracy * (1 / 3)) + if(prob(50)) + amount -= inaccurate + if(prob(50)) + amount += inaccurate + return DisplayTimeText(max(1, amount)) + /obj/item/mass_spectrometer desc = "A hand-held mass spectrometer which identifies trace chemicals in a blood sample. Inject sample with syringe." name = "mass-spectrometer" diff --git a/code/game/turfs/space/transit.dm b/code/game/turfs/space/transit.dm index 611ff1656f3..2831894e3ea 100644 --- a/code/game/turfs/space/transit.dm +++ b/code/game/turfs/space/transit.dm @@ -94,8 +94,7 @@ var/max = world.maxx-TRANSITIONEDGE var/min = 1+TRANSITIONEDGE - var/datum/space_level/dest = pick(levels_by_trait(REACHABLE)) - var/_z = dest.zpos //select a random space zlevel + var/_z = pick(levels_by_trait(REACHABLE)) //select a random space zlevel //now select coordinates for a border turf var/_x diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 5039146b1c3..fe487ae6431 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -80,7 +80,6 @@ Security Level - Delta
Create Weather
Weather - Ash Storm   - Weather - Advanced Darkness  
"} diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 1bd231ba5a9..ece60118fa0 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -2727,48 +2727,6 @@ for(var/mob/M in player_list) if(M.stat != 2) M.show_message(text("The chilling wind suddenly stops..."), 1) -/* if("shockwave") - ok = 1 - to_chat(world, "ALERT: STATION STRESS CRITICAL") - sleep(60) - to_chat(world, "ALERT: STATION STRESS CRITICAL. TOLERABLE LEVELS EXCEEDED!") - sleep(80) - to_chat(world, "ALERT: STATION STRUCTURAL STRESS CRITICAL. SAFETY MECHANISMS FAILED!") - sleep(40) - for(var/mob/M in world) - shake_camera(M, 400, 1) - for(var/obj/structure/window/W in world) - spawn(0) - sleep(rand(10,400)) - W.ex_act(rand(2,1)) - for(var/obj/structure/grille/G in world) - spawn(0) - sleep(rand(20,400)) - G.ex_act(rand(2,1)) - for(var/obj/machinery/door/D in world) - spawn(0) - sleep(rand(20,400)) - D.ex_act(rand(2,1)) - for(var/turf/station/floor/Floor in world) - spawn(0) - sleep(rand(30,400)) - Floor.ex_act(rand(2,1)) - for(var/obj/structure/cable/Cable in world) - spawn(0) - sleep(rand(30,400)) - Cable.ex_act(rand(2,1)) - for(var/obj/structure/closet/Closet in world) - spawn(0) - sleep(rand(30,400)) - Closet.ex_act(rand(2,1)) - for(var/obj/machinery/Machinery in world) - spawn(0) - sleep(rand(30,400)) - Machinery.ex_act(rand(1,3)) - for(var/turf/station/wall/Wall in world) - spawn(0) - sleep(rand(30,400)) - Wall.ex_act(rand(2,1)) */ if("lightout") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","LO") @@ -2793,7 +2751,7 @@ var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "Yes", "No") if(sure == "No") return - weather_master.run_weather("the floor is lava") + SSweather.run_weather(/datum/weather/floor_is_lava) message_admins("[key_name_admin(usr)] made the floor lava") if("fakelava") feedback_inc("admin_secrets_fun_used", 1) @@ -2801,7 +2759,7 @@ var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "Yes", "No") if(sure == "No") return - weather_master.run_weather("fake lava") + SSweather.run_weather(/datum/weather/floor_is_lava/fake) message_admins("[key_name_admin(usr)] made aesthetic lava on the floor") if("weatherashstorm") feedback_inc("admin_secrets_fun_used", 1) @@ -2809,16 +2767,8 @@ var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "Yes", "No") if(sure == "No") return - weather_master.run_weather("ash storm") + SSweather.run_weather(/datum/weather/ash_storm) message_admins("[key_name_admin(usr)] spawned an ash storm on the mining asteroid") - if("weatherdarkness") - feedback_inc("admin_secrets_fun_used", 1) - feedback_add_details("admin_secrets_fun_used", "WD") - var/sure = alert(usr, "Are you sure you want to do this?", "Confirmation", "Yes", "No") - if(sure == "No") - return - weather_master.run_weather("advanced darkness") - message_admins("[key_name_admin(usr)] made the station go through advanced darkness") if("retardify") feedback_inc("admin_secrets_fun_used",1) feedback_add_details("admin_secrets_fun_used","RET") diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm index 0f2da54818c..4b822dd718e 100644 --- a/code/modules/events/radiation_storm.dm +++ b/code/modules/events/radiation_storm.dm @@ -1,70 +1,11 @@ -/datum/event/radiation_storm - announceWhen = 1 - var/safe_zones = list( - /area/maintenance, - /area/crew_quarters/sleep, - /area/security/brig, - /area/shuttle, - /area/vox_station, - /area/syndicate_station - ) - +/datum/event/radiation_storm/setup() + startWhen = 3 + endWhen = startWhen + 1 + announceWhen = 1 /datum/event/radiation_storm/announce() - // Don't do anything, we want to pack the announcement with the actual event - -/datum/event/radiation_storm/proc/is_safe_zone(var/area/A) - for(var/szt in safe_zones) - if(istype(A, szt)) - return 1 - return 0 + priority_announcement.Announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", 'sound/ai/radiation.ogg') + //sound not longer matches the text, but an audible warning is probably good /datum/event/radiation_storm/start() - spawn() - event_announcement.Announce("High levels of radiation detected near the station. Please evacuate into one of the shielded maintenance tunnels.", "Anomaly Alert", new_sound = 'sound/AI/radiation.ogg') - - for(var/area/A in world) - if(!is_station_level(A.z) || is_safe_zone(A)) - continue - A.radiation_alert() - - make_maint_all_access() - - sleep(600) - - event_announcement.Announce("The station has entered the radiation belt. Please remain in a sheltered area until we have passed the radiation belt.", "Anomaly Alert") - - for(var/i = 0, i < 10, i++) - for(var/mob/living/carbon/human/H in living_mob_list) - var/armor = H.getarmor(type = "rad") - if((RADIMMUNE in H.species.species_traits) || armor >= 100) // Leave radiation-immune species/fully rad armored players completely unaffected - continue - var/turf/T = get_turf(H) - if(!T) - continue - if(!is_station_level(T.z) || is_safe_zone(T.loc)) - continue - - if(istype(H,/mob/living/carbon/human)) - H.apply_effect((rand(15,35)),IRRADIATE,0) - if(prob(5)) - H.apply_effect((rand(40,70)),IRRADIATE,0) - if(prob(75)) - randmutb(H) // Applies bad mutation - domutcheck(H,null,1) - else - randmutg(H) // Applies good mutation - domutcheck(H,null,1) - - sleep(100) - - event_announcement.Announce("The station has passed the radiation belt. Please report to medbay if you experience any unusual symptoms. Maintenance will lose all access again shortly.", "Anomaly Alert") - - for(var/area/A in world) - if(!is_station_level(A.z) || is_safe_zone(A)) - continue - A.reset_radiation_alert() - - sleep(600) // Want to give them time to get out of maintenance. - - revoke_maint_all_access() + SSweather.run_weather(/datum/weather/rad_storm) \ No newline at end of file diff --git a/code/modules/mining/lavaland/loot/legion_loot.dm b/code/modules/mining/lavaland/loot/legion_loot.dm index 210710db4d9..f11d6162f55 100644 --- a/code/modules/mining/lavaland/loot/legion_loot.dm +++ b/code/modules/mining/lavaland/loot/legion_loot.dm @@ -5,7 +5,6 @@ item_state = "staffofstorms" icon = 'icons/obj/guns/magic.dmi' slot_flags = SLOT_BACK - item_state = "staffofstorms" w_class = WEIGHT_CLASS_BULKY force = 25 damtype = BURN @@ -19,34 +18,36 @@ return var/area/user_area = get_area(user) + var/turf/user_turf = get_turf(user) + if(!user_area || !user_turf) + to_chat(user, "Something is preventing you from using the staff here.") + return var/datum/weather/A - var/z_level_name = space_manager.levels_by_name[user.z] - for(var/V in weather_master.existing_weather) + for(var/V in SSweather.processing) var/datum/weather/W = V - if(W.target_z == z_level_name && W.area_type == user_area.type) + if((user_turf.z in W.impacted_z_levels) && W.area_type == user_area.type) A = W break - if(A) + if(A) if(A.stage != END_STAGE) if(A.stage == WIND_DOWN_STAGE) to_chat(user, "The storm is already ending! It would be a waste to use the staff now.") return user.visible_message("[user] holds [src] skywards as an orange beam travels into the sky!", \ "You hold [src] skyward, dispelling the storm!") - playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0) + playsound(user, 'sound/magic/staff_change.ogg', 200, 0) A.wind_down() return else - A = new storm_type + A = new storm_type(list(user_turf.z)) A.name = "staff storm" A.area_type = user_area.type - A.target_z = z_level_name A.telegraph_duration = 100 A.end_duration = 100 user.visible_message("[user] holds [src] skywards as red lightning crackles into the sky!", \ "You hold [src] skyward, calling down a terrible storm!") - playsound(user, 'sound/magic/Staff_Change.ogg', 200, 0) + playsound(user, 'sound/magic/staff_change.ogg', 200, 0) A.telegraph() storm_cooldown = world.time + 200 diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index ace8ab1b621..1cb1bc5f3b0 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -208,3 +208,7 @@ /mob/proc/AdjustWeakened() return + +/mob/proc/adjust_bodytemperature(amount, min_temp = 0, max_temp = INFINITY) + if(bodytemperature > min_temp && bodytemperature < max_temp) + bodytemperature = Clamp(bodytemperature + amount, min_temp, max_temp) \ No newline at end of file diff --git a/code/modules/space_management/level_traits.dm b/code/modules/space_management/level_traits.dm index ae5d6447aae..39b584df64d 100644 --- a/code/modules/space_management/level_traits.dm +++ b/code/modules/space_management/level_traits.dm @@ -1,62 +1,63 @@ /proc/is_level_reachable(z) - return check_level_trait(z, REACHABLE) + return check_level_trait(z, REACHABLE) /proc/is_station_level(z) - return check_level_trait(z, STATION_LEVEL) + return check_level_trait(z, STATION_LEVEL) /proc/is_station_contact(z) - return check_level_trait(z, STATION_CONTACT) + return check_level_trait(z, STATION_CONTACT) /proc/is_teleport_allowed(z) - return !check_level_trait(z, BLOCK_TELEPORT) + return !check_level_trait(z, BLOCK_TELEPORT) /proc/is_admin_level(z) - return check_level_trait(z, ADMIN_LEVEL) + return check_level_trait(z, ADMIN_LEVEL) /proc/is_away_level(z) - return check_level_trait(z, AWAY_LEVEL) + return check_level_trait(z, AWAY_LEVEL) /proc/is_mining_level(z) - return check_level_trait(z, ORE_LEVEL) + return check_level_trait(z, ORE_LEVEL) /proc/is_ai_allowed(z) - return check_level_trait(z, AI_OK) + return check_level_trait(z, AI_OK) /proc/level_blocks_magic(z) - return check_level_trait(z, IMPEDES_MAGIC) + return check_level_trait(z, IMPEDES_MAGIC) /proc/level_boosts_signal(z) - return check_level_trait(z, BOOSTS_SIGNAL) + return check_level_trait(z, BOOSTS_SIGNAL) // Used for the nuke disk, or for checking if players survived through xenos /proc/is_secure_level(z) - var/secure = check_level_trait(z, STATION_LEVEL) - if(!secure) - // This is to allow further admin levels later, other than centcomm - secure = (z == level_name_to_num(CENTCOMM)) - return secure + var/secure = check_level_trait(z, STATION_LEVEL) + if(!secure) + // This is to allow further admin levels later, other than centcomm + secure = (z == level_name_to_num(CENTCOMM)) + return secure var/list/default_map_traits = MAP_TRANSITION_CONFIG + /proc/check_level_trait(z, trait) - if(!z) - return 0 // If you're nowhere, you have no traits - var/list/trait_list - if(space_manager.initialized) - var/datum/space_level/S = space_manager.get_zlev(z) - trait_list = S.flags - else - trait_list = default_map_traits[z] - trait_list = trait_list["attributes"] - return (trait in trait_list) + if(!z) + return 0 // If you're nowhere, you have no traits + var/list/trait_list + if(space_manager.initialized) + var/datum/space_level/S = space_manager.get_zlev(z) + trait_list = S.flags + else + trait_list = default_map_traits[z] + trait_list = trait_list["attributes"] + return (trait in trait_list) /proc/levels_by_trait(trait) - var/list/result = list() - for(var/A in space_manager.z_list) - var/datum/space_level/S = space_manager.z_list[A] - if(trait in S.flags) - result |= S - return result + var/list/result = list() + for(var/A in space_manager.z_list) + var/datum/space_level/S = space_manager.z_list[A] + if(trait in S.flags) + result |= S.zpos + return result /proc/level_name_to_num(name) - var/datum/space_level/S = space_manager.get_zlev_by_name(name) - return S.zpos + var/datum/space_level/S = space_manager.get_zlev_by_name(name) + return S.zpos \ No newline at end of file diff --git a/code/modules/space_management/zlevel_manager.dm b/code/modules/space_management/zlevel_manager.dm index 087a70657ed..acb1cf5c0a0 100644 --- a/code/modules/space_management/zlevel_manager.dm +++ b/code/modules/space_management/zlevel_manager.dm @@ -12,6 +12,8 @@ var/global/datum/zlev_manager/space_manager = new var/datum/spacewalk_grid/linkage_map var/initialized = 0 + var/list/areas_in_z = list() + // Populate our space level list // and prepare space transitions /datum/zlev_manager/proc/initialize() @@ -166,4 +168,4 @@ var/global/datum/zlev_manager/space_manager = new var/datum/space_level/heap/heap = z_list["[C.zpos]"] if(!istype(heap)) throw EXCEPTION("Attempted to free chunk at invalid z-level ([C.x],[C.y],[C.zpos]) [C.width]x[C.height]") - heap.free(C) + heap.free(C) \ No newline at end of file diff --git a/icons/effects/weather_effects.dmi b/icons/effects/weather_effects.dmi index 215cf53556f..da1523706e2 100644 Binary files a/icons/effects/weather_effects.dmi and b/icons/effects/weather_effects.dmi differ diff --git a/icons/obj/status_display.dmi b/icons/obj/status_display.dmi index b131da89349..81ccc415de1 100644 Binary files a/icons/obj/status_display.dmi and b/icons/obj/status_display.dmi differ diff --git a/paradise.dme b/paradise.dme index 8764c0e8a63..095e5ad2a78 100644 --- a/paradise.dme +++ b/paradise.dme @@ -198,7 +198,6 @@ #include "code\controllers\Processes\obj.dm" #include "code\controllers\Processes\shuttles.dm" #include "code\controllers\Processes\ticker.dm" -#include "code\controllers\Processes\weather.dm" #include "code\controllers\ProcessScheduler\core\process.dm" #include "code\controllers\ProcessScheduler\core\processScheduler.dm" #include "code\controllers\subsystem\air.dm" @@ -213,6 +212,7 @@ #include "code\controllers\subsystem\sun.dm" #include "code\controllers\subsystem\throwing.dm" #include "code\controllers\subsystem\timer.dm" +#include "code\controllers\subsystem\weather.dm" #include "code\controllers\subsystem\processing\processing.dm" #include "code\datums\action.dm" #include "code\datums\ai_law_sets.dm" @@ -313,6 +313,7 @@ #include "code\datums\helper_datums\topic_input.dm" #include "code\datums\looping_sounds\looping_sound.dm" #include "code\datums\looping_sounds\machinery_sounds.dm" +#include "code\datums\looping_sounds\weather.dm" #include "code\datums\outfits\outfit.dm" #include "code\datums\outfits\outfit_admin.dm" #include "code\datums\ruins\space.dm" @@ -352,7 +353,10 @@ #include "code\datums\status_effects\status_effect.dm" #include "code\datums\vr\level.dm" #include "code\datums\weather\weather.dm" -#include "code\datums\weather\weather_types.dm" +#include "code\datums\weather\weather_types\ash_storm.dm" +#include "code\datums\weather\weather_types\floor_is_lava.dm" +#include "code\datums\weather\weather_types\radiation_storm.dm" +#include "code\datums\weather\weather_types\snow_storm.dm" #include "code\datums\wires\airlock.dm" #include "code\datums\wires\alarm.dm" #include "code\datums\wires\apc.dm" diff --git a/sound/lavaland/ash_storm_end.ogg b/sound/lavaland/ash_storm_end.ogg deleted file mode 100644 index f9b01453dda..00000000000 Binary files a/sound/lavaland/ash_storm_end.ogg and /dev/null differ diff --git a/sound/lavaland/ash_storm_start.ogg b/sound/lavaland/ash_storm_start.ogg deleted file mode 100644 index 4b9bebffd08..00000000000 Binary files a/sound/lavaland/ash_storm_start.ogg and /dev/null differ diff --git a/sound/lavaland/ash_storm_windup.ogg b/sound/lavaland/ash_storm_windup.ogg deleted file mode 100644 index a9f0fa3270e..00000000000 Binary files a/sound/lavaland/ash_storm_windup.ogg and /dev/null differ diff --git a/sound/weather/ashstorm/inside/active_end.ogg b/sound/weather/ashstorm/inside/active_end.ogg new file mode 100644 index 00000000000..959bf5773eb Binary files /dev/null and b/sound/weather/ashstorm/inside/active_end.ogg differ diff --git a/sound/weather/ashstorm/inside/active_mid1.ogg b/sound/weather/ashstorm/inside/active_mid1.ogg new file mode 100644 index 00000000000..95244cd2b7c Binary files /dev/null and b/sound/weather/ashstorm/inside/active_mid1.ogg differ diff --git a/sound/weather/ashstorm/inside/active_mid2.ogg b/sound/weather/ashstorm/inside/active_mid2.ogg new file mode 100644 index 00000000000..a45584b9f31 Binary files /dev/null and b/sound/weather/ashstorm/inside/active_mid2.ogg differ diff --git a/sound/weather/ashstorm/inside/active_mid3.ogg b/sound/weather/ashstorm/inside/active_mid3.ogg new file mode 100644 index 00000000000..be2e672fa0e Binary files /dev/null and b/sound/weather/ashstorm/inside/active_mid3.ogg differ diff --git a/sound/weather/ashstorm/inside/active_start.ogg b/sound/weather/ashstorm/inside/active_start.ogg new file mode 100644 index 00000000000..3efab12ef26 Binary files /dev/null and b/sound/weather/ashstorm/inside/active_start.ogg differ diff --git a/sound/weather/ashstorm/inside/weak_end.ogg b/sound/weather/ashstorm/inside/weak_end.ogg new file mode 100644 index 00000000000..416b75a9b84 Binary files /dev/null and b/sound/weather/ashstorm/inside/weak_end.ogg differ diff --git a/sound/weather/ashstorm/inside/weak_mid1.ogg b/sound/weather/ashstorm/inside/weak_mid1.ogg new file mode 100644 index 00000000000..d3211c6b5fc Binary files /dev/null and b/sound/weather/ashstorm/inside/weak_mid1.ogg differ diff --git a/sound/weather/ashstorm/inside/weak_mid2.ogg b/sound/weather/ashstorm/inside/weak_mid2.ogg new file mode 100644 index 00000000000..b6491a7afb8 Binary files /dev/null and b/sound/weather/ashstorm/inside/weak_mid2.ogg differ diff --git a/sound/weather/ashstorm/inside/weak_mid3.ogg b/sound/weather/ashstorm/inside/weak_mid3.ogg new file mode 100644 index 00000000000..95238c72d40 Binary files /dev/null and b/sound/weather/ashstorm/inside/weak_mid3.ogg differ diff --git a/sound/weather/ashstorm/inside/weak_start.ogg b/sound/weather/ashstorm/inside/weak_start.ogg new file mode 100644 index 00000000000..59abf1937dc Binary files /dev/null and b/sound/weather/ashstorm/inside/weak_start.ogg differ diff --git a/sound/weather/ashstorm/outside/active_end.ogg b/sound/weather/ashstorm/outside/active_end.ogg new file mode 100644 index 00000000000..95149d846cc Binary files /dev/null and b/sound/weather/ashstorm/outside/active_end.ogg differ diff --git a/sound/weather/ashstorm/outside/active_mid1.ogg b/sound/weather/ashstorm/outside/active_mid1.ogg new file mode 100644 index 00000000000..189528ab569 Binary files /dev/null and b/sound/weather/ashstorm/outside/active_mid1.ogg differ diff --git a/sound/weather/ashstorm/outside/active_mid2.ogg b/sound/weather/ashstorm/outside/active_mid2.ogg new file mode 100644 index 00000000000..92317f2e0a7 Binary files /dev/null and b/sound/weather/ashstorm/outside/active_mid2.ogg differ diff --git a/sound/weather/ashstorm/outside/active_mid3.ogg b/sound/weather/ashstorm/outside/active_mid3.ogg new file mode 100644 index 00000000000..34846bfd42c Binary files /dev/null and b/sound/weather/ashstorm/outside/active_mid3.ogg differ diff --git a/sound/weather/ashstorm/outside/active_start.ogg b/sound/weather/ashstorm/outside/active_start.ogg new file mode 100644 index 00000000000..8b3acf1a153 Binary files /dev/null and b/sound/weather/ashstorm/outside/active_start.ogg differ diff --git a/sound/weather/ashstorm/outside/weak_end.ogg b/sound/weather/ashstorm/outside/weak_end.ogg new file mode 100644 index 00000000000..55db2fc3565 Binary files /dev/null and b/sound/weather/ashstorm/outside/weak_end.ogg differ diff --git a/sound/weather/ashstorm/outside/weak_mid1.ogg b/sound/weather/ashstorm/outside/weak_mid1.ogg new file mode 100644 index 00000000000..56faa9ad26c Binary files /dev/null and b/sound/weather/ashstorm/outside/weak_mid1.ogg differ diff --git a/sound/weather/ashstorm/outside/weak_mid2.ogg b/sound/weather/ashstorm/outside/weak_mid2.ogg new file mode 100644 index 00000000000..0c836ad220a Binary files /dev/null and b/sound/weather/ashstorm/outside/weak_mid2.ogg differ diff --git a/sound/weather/ashstorm/outside/weak_mid3.ogg b/sound/weather/ashstorm/outside/weak_mid3.ogg new file mode 100644 index 00000000000..f2cbfb0f4b9 Binary files /dev/null and b/sound/weather/ashstorm/outside/weak_mid3.ogg differ diff --git a/sound/weather/ashstorm/outside/weak_start.ogg b/sound/weather/ashstorm/outside/weak_start.ogg new file mode 100644 index 00000000000..1ac59c36f05 Binary files /dev/null and b/sound/weather/ashstorm/outside/weak_start.ogg differ