diff --git a/code/_helpers/events.dm b/code/_helpers/events.dm new file mode 100644 index 0000000000..74e047e811 --- /dev/null +++ b/code/_helpers/events.dm @@ -0,0 +1,15 @@ +/proc/get_station_areas(var/list/area/excluded_areas) + var/list/area/grand_list_of_areas = list() + // Assemble areas that all exists (See DM reference if you are confused about loop labels) + looping_station_areas: + for(var/parentpath in global.the_station_areas) + // Check its not excluded + for(var/excluded_path in excluded_areas) + if(ispath(parentpath, excluded_path)) + continue looping_station_areas + // Otherwise add it and all subtypes that exist on the map to our grand list + for(var/areapath in typesof(parentpath)) + var/area/A = locate(areapath) // Check if it actually exists + if(istype(A) && A.z in using_map.player_levels) + grand_list_of_areas += A + return grand_list_of_areas \ No newline at end of file diff --git a/code/modules/events/atmos_leak.dm b/code/modules/events/atmos_leak.dm index 46c28b7adf..e0a3a55549 100644 --- a/code/modules/events/atmos_leak.dm +++ b/code/modules/events/atmos_leak.dm @@ -26,19 +26,7 @@ gas_choices += "volatile_fuel" // Dangerous and no default atmos setup! gas_type = pick(gas_choices) - // Assemble areas that all exists (See DM reference if you are confused about loop labels) - var/list/area/grand_list_of_areas = list() - looping_station_areas: - for(var/parentpath in global.the_station_areas) - // Check its not excluded - for(var/excluded_path in excluded) - if(ispath(parentpath, excluded_path)) - continue looping_station_areas - // Otherwise add it and all subtypes that exist on the map to our grand list - for(var/areapath in typesof(parentpath)) - var/area/A = locate(areapath) // Check if it actually exists - if(istype(A) && A.z in using_map.player_levels) - grand_list_of_areas += A + var/list/area/grand_list_of_areas = get_station_areas(excluded) // Okay, now lets try and pick a target! Lets try 10 times, otherwise give up for(var/i in 1 to 10) diff --git a/code/modules/events/electrified_door.dm b/code/modules/events/electrified_door.dm new file mode 100644 index 0000000000..7802f971ca --- /dev/null +++ b/code/modules/events/electrified_door.dm @@ -0,0 +1,32 @@ +/datum/event/electrified_door + var/obj/machinery/door/airlock/chosen_door + var/list/area/excluded = list( + /area/shuttle, + /area/crew_quarters + ) + +/datum/event/electrified_door/setup() + var/list/area/grand_list_of_areas = get_station_areas(excluded) + //try 10 times + for(var/i in 1 to 10) + var/area/A = pick(grand_list_of_areas) + var/list/obj/machinery/door/airlock/target_doors = list() + for(var/obj/machinery/door/airlock/target_door in A.contents) + target_doors += target_door + target_doors = shuffle(target_doors) + + for(var/obj/machinery/door/airlock/target_door in target_doors) + if(!target_door.isElectrified() && target_door.arePowerSystemsOn() && target_door.maxhealth == target_door.health) + chosen_door = target_door + return + +/datum/event/electrified_door/start() + + if(!chosen_door) + return + chosen_door.set_safeties(0) + chosen_door.electrify(-1) + chosen_door.unlock() + chosen_door.health = chosen_door.maxhealth / 6 + chosen_door.aiControlDisabled = 1 + chosen_door.update_icon() diff --git a/code/modules/events/escaped_slimes.dm b/code/modules/events/escaped_slimes.dm new file mode 100644 index 0000000000..9cc2f5a7fc --- /dev/null +++ b/code/modules/events/escaped_slimes.dm @@ -0,0 +1,44 @@ +/datum/event/escaped_slimes + announceWhen = 90 + endWhen = 90 + 15 + 1 + var/spawncount + var/list/possible_slimes = list( + /mob/living/simple_animal/slime/purple, + /mob/living/simple_animal/slime/orange, + /mob/living/simple_animal/slime/metal, + /mob/living/simple_animal/slime/yellow, + /mob/living/simple_animal/slime/dark_purple, + /mob/living/simple_animal/slime/silver, + /mob/living/simple_animal/slime/ruby, + /mob/living/simple_animal/slime/cerulean, + /mob/living/simple_animal/slime/red, + /mob/living/simple_animal/slime/green, + /mob/living/simple_animal/slime/pink, + /mob/living/simple_animal/slime/gold, + /mob/living/simple_animal/slime/oil, + /mob/living/simple_animal/slime/emerald, + ) + + +/datum/event/escaped_slimes/setup() + announceWhen = rand(announceWhen, announceWhen + 60) + spawncount = rand(2 * severity, 4 * severity) //spiderlings only have a 50% chance to grow big and strong + +/datum/event/escaped_slimes/announce() + command_announcement.Announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", new_sound = 'sound/AI/aliens.ogg') + sleep(15) + command_announcement.Announce("The previously unidentified lifesigns have been identified as escaped slimes from Xenobiology. Secure any exterior access, including ducting and ventilation, taking care to return the slimes to their proper confinement.", "Lifesign Alert") + + +/datum/event/escaped_slimes/start() + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in world) + if(temp_vent.network && temp_vent.loc.z in using_map.station_levels) //borrowed from spiders event, but it works. Distribute the slimes only in rooms with vents + vents += temp_vent + + while((spawncount > 0) && vents.len) + var/obj/vent = pick(vents) + var/slime_type = pick(possible_slimes) + new slime_type(vent.loc, 1) + vents -= vent + spawncount-- diff --git a/code/modules/events/wallrot.dm b/code/modules/events/wallrot.dm index 096c7f8965..5aede8a894 100644 --- a/code/modules/events/wallrot.dm +++ b/code/modules/events/wallrot.dm @@ -1,20 +1,24 @@ -datum/event/wallrot/setup() +/datum/event/wallrot + var/turf/simulated/wall/center + +/datum/event/wallrot/setup() announceWhen = rand(0, 300) endWhen = announceWhen + 1 -datum/event/wallrot/announce() - command_announcement.Announce("Harmful fungi detected on the colony. Station structures may be contaminated.", "Biohazard Alert") + // 100 attempts + for(var/i=0, i<100, i++) + var/turf/candidate = locate(rand(1, world.maxx), rand(1, world.maxy), 1) + if(istype(candidate, /turf/simulated/wall)) + center = candidate + return 1 + return 0 -datum/event/wallrot/start() +/datum/event/wallrot/announce() + if(center) + command_announcement.Announce("Harmful fungi detected on the colony nearby [center.loc.name]. Station structures may be contaminated.", "Biohazard Alert") + +/datum/event/wallrot/start() spawn() - var/turf/simulated/wall/center = null - - // 100 attempts - for(var/i=0, i<100, i++) - var/turf/candidate = locate(rand(1, world.maxx), rand(1, world.maxy), 1) - if(istype(candidate, /turf/simulated/wall)) - center = candidate - if(center) // Make sure at least one piece of wall rots! center.rot() diff --git a/code/modules/events/window_break.dm b/code/modules/events/window_break.dm new file mode 100644 index 0000000000..786b2df424 --- /dev/null +++ b/code/modules/events/window_break.dm @@ -0,0 +1,73 @@ +/datum/event/window_break + var/obj/structure/window/chosen_window + var/list/obj/structure/window/collateral_windows + var/turf/chosen_location + var/list/area/excluded = list( + /area/shuttle, + /area/crew_quarters + ) + +/datum/event/window_break/setup() + var/list/area/grand_list_of_areas = get_station_areas(excluded) + //try 10 times + for(var/i in 1 to 10) + var/area/A = pick(grand_list_of_areas) + var/list/obj/structure/window/possible_target_windows = list() + for(var/obj/structure/window/target_window in A.contents) + possible_target_windows += target_window + possible_target_windows = shuffle(possible_target_windows) + + for(var/obj/structure/window/target_window in possible_target_windows) + //if() don't have any conditions, for isn't strictly necessary + chosen_window = target_window + chosen_location = chosen_window.loc + collateral_windows = gather_collateral_windows(chosen_window) + announceWhen = (collateral_windows.len + 1) * 20 + endWhen = announceWhen + 1 + return + +//TL;DR: breadth first search for all connected turfs with windows +/datum/event/window_break/proc/gather_collateral_windows(var/obj/structure/window/target_window) + var/list/turf/frontier_set = list(target_window.loc) + var/list/obj/structure/window/result_set = list() + var/list/turf/explored_set = list() + + while(frontier_set.len > 0) + var/turf/current = frontier_set[1] + frontier_set -= current + explored_set += current + + var/contains_windows = 0 + for(var/obj/structure/window/to_add in current.contents) + contains_windows = 1 + result_set += to_add + + if(contains_windows) + //add adjacent turfs to be checked for windows as well + var/turf/neighbor = locate(current.x + 1, current.y, current.z) + if(!(neighbor in frontier_set) && !(neighbor in explored_set)) + frontier_set += neighbor + neighbor = locate(current.x - 1, current.y, current.z) + if(!(neighbor in frontier_set) && !(neighbor in explored_set)) + frontier_set += neighbor + neighbor = locate(current.x, current.y + 1, current.z) + if(!(neighbor in frontier_set) && !(neighbor in explored_set)) + frontier_set += neighbor + neighbor = locate(current.x, current.y - 1, current.z) + if(!(neighbor in frontier_set) && !(neighbor in explored_set)) + frontier_set += neighbor + return result_set + + + +/datum/event/window_break/start() + if(!chosen_window) + return + chosen_window.shatter(0) + + for(var/obj/structure/window/current_collateral in collateral_windows) + sleep(rand(1,20)) + current_collateral.take_damage(current_collateral.health - (current_collateral.maxhealth / 5)) //set to 1/5th health + +/datum/event/window_break/announce() + command_announcement.Announce("Structural integrity of windows at [chosen_location.loc.name] is failing. Immediate repair or replacement is advised.", "Structural Alert") diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm new file mode 100644 index 0000000000..a9581341c5 --- /dev/null +++ b/code/modules/events/wormholes.dm @@ -0,0 +1,9 @@ +/datum/event/wormholes + startWhen = 0 + endWhen = 80 + +/datum/event/wormholes/start() + wormhole_event() + +/datum/event/wormholes/end() + command_announcement.Announce("There are no more space-time anomalies detected on the station.", "Anomaly Alert")