From b3fe83f4d3fdb92ff01e4bd6132ab951ecb24e0a Mon Sep 17 00:00:00 2001 From: ReddeyfishVor <36580397+ReddeyfishVor@users.noreply.github.com> Date: Fri, 6 Apr 2018 09:35:13 -0700 Subject: [PATCH] New events, broken windows and doors (#102) * Add electrified door event * Add more verbose announcement to wallrot * Add window breaking event * Add window breakage to event rotation --- code/_helpers/events.dm | 15 +++++ code/modules/events/atmos_leak.dm | 14 +---- code/modules/events/electrified_door.dm | 32 ++++++++++ code/modules/events/event_container_vr.dm | 6 +- code/modules/events/wallrot.dm | 28 +++++---- code/modules/events/window_break.dm | 73 +++++++++++++++++++++++ vorestation.dme | 3 + 7 files changed, 144 insertions(+), 27 deletions(-) create mode 100644 code/_helpers/events.dm create mode 100644 code/modules/events/electrified_door.dm create mode 100644 code/modules/events/window_break.dm 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 0b9da559c9..e9fea3ff66 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/event_container_vr.dm b/code/modules/events/event_container_vr.dm index bf1e64c0eb..1866142380 100644 --- a/code/modules/events/event_container_vr.dm +++ b/code/modules/events/event_container_vr.dm @@ -32,10 +32,11 @@ // Bluescreens APCs, but they still work new /datum/event_meta(EVENT_LEVEL_MUNDANE, "APC Damage", /datum/event/apc_damage, 20, list(ASSIGNMENT_ENGINEER = 20)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Brand Intelligence",/datum/event/brand_intelligence,20, list(ASSIGNMENT_JANITOR = 25), 1), - new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 40)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Canister Leak", /datum/event/canister_leak, 10, list(ASSIGNMENT_ENGINEER = 20)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 50, list(ASSIGNMENT_ENGINEER = 20), 1, 0, 50), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Economic News", /datum/event/economic_event, 300), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Electrified Door", /datum/event/electrified_door, 0, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 10)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Lost Carp", /datum/event/carp_migration, 20, list(ASSIGNMENT_SECURITY = 10), 1), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Meteor Shower", /datum/event/meteor_wave, -15, list(ASSIGNMENT_ENGINEER = 5), 1), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15), @@ -47,6 +48,7 @@ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100), 1), // Rot only weakens walls, not destroy them new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 30, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50), 1), + new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Window Damage", /datum/event/window_break, 10, list(ASSIGNMENT_ENGINEER = 20)), new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Viral Infection", /datum/event/viral_infection, -25, list(ASSIGNMENT_MEDICAL = 5), 1), ) add_disabled_events(list( @@ -61,7 +63,7 @@ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Appendicitis", /datum/event/spontaneous_appendicitis, 0, list(ASSIGNMENT_MEDICAL = 30), 1), // Leaks gas into an unoccupied room. new /datum/event_meta(EVENT_LEVEL_MODERATE, "Atmos Leak", /datum/event/atmos_leak, 150, list(ASSIGNMENT_ENGINEER = 25), 1), - new /datum/event_meta(EVENT_LEVEL_MAJOR, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20)), + new /datum/event_meta(EVENT_LEVEL_MAJOR, "Camera Damage", /datum/event/camera_damage, 20, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_AI = 40)), // Just disables comms for a short while. new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120), 1), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Carp School", /datum/event/carp_migration, -50, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_SECURITY = 30), 1), 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..1d44ddae2d --- /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) * 5 + 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,5)) + 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") \ No newline at end of file diff --git a/vorestation.dme b/vorestation.dme index 1976cec474..20fa6f133e 100644 --- a/vorestation.dme +++ b/vorestation.dme @@ -72,6 +72,7 @@ #include "code\_compatibility\509\type2type.dm" #include "code\_helpers\_global_objects.dm" #include "code\_helpers\atmospherics.dm" +#include "code\_helpers\events.dm" #include "code\_helpers\files.dm" #include "code\_helpers\game.dm" #include "code\_helpers\global_lists.dm" @@ -1642,6 +1643,7 @@ #include "code\modules\events\communications_blackout.dm" #include "code\modules\events\dust.dm" #include "code\modules\events\electrical_storm.dm" +#include "code\modules\events\electrified_door.dm" #include "code\modules\events\event.dm" #include "code\modules\events\event_container.dm" #include "code\modules\events\event_container_vr.dm" @@ -1672,6 +1674,7 @@ #include "code\modules\events\supply_demand.dm" #include "code\modules\events\viral_infection.dm" #include "code\modules\events\wallrot.dm" +#include "code\modules\events\window_break.dm" #include "code\modules\events\wormholes.dm" #include "code\modules\examine\examine.dm" #include "code\modules\examine\stat_icons.dm"