diff --git a/code/__DEFINES/dcs/signals/signals_event.dm b/code/__DEFINES/dcs/signals/signals_event.dm new file mode 100644 index 00000000000..82f751e9918 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_event.dm @@ -0,0 +1,7 @@ +// Grey Tide event signals +/// Sent when the Grey Tide event begins affecting the station. +/// (list/area/greytide_areas) +#define COMSIG_GLOB_GREY_TIDE "grey_tide" + +/// A different signal, used specifically for flickering the lights during the event +#define COMSIG_GLOB_GREY_TIDE_LIGHT "grey_tide_light" diff --git a/code/game/machinery/airlock_control.dm b/code/game/machinery/airlock_control.dm index 6e30493d787..17294c3b3b6 100644 --- a/code/game/machinery/airlock_control.dm +++ b/code/game/machinery/airlock_control.dm @@ -6,6 +6,10 @@ var/airlock_state var/frequency +/obj/machinery/door/airlock/Initialize(mapload) + . = ..() + RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) + /// Forces the airlock to unbolt and open /obj/machinery/door/airlock/proc/secure_open() locked = FALSE @@ -31,6 +35,17 @@ locked = FALSE return ..() +/obj/machinery/door/airlock/proc/grey_tide(datum/source, list/grey_tide_areas) + SIGNAL_HANDLER + + if(!is_station_level(z) || critical_machine) + return //Skip doors in critical positions, such as the SM chamber. + + for(var/area_type in grey_tide_areas) + if(!istype(get_area(src), area_type)) + continue + INVOKE_ASYNC(src, PROC_REF(prison_open)) //Sleep gets called further down in open(), so we have to invoke async + /obj/machinery/airlock_sensor icon = 'icons/obj/airlock_machines.dmi' icon_state = "airlock_sensor_off" diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index 501c1ca3817..df3ca1b3a1b 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -58,6 +58,8 @@ if(!length(doors) && !length(flashers) && length(closets)) atom_break() + RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) + //Main door timer loop, if it's timing and time is >0 reduce time by 1. // if it's less than 0, open door, reset timer // update the door_timer window and the icon @@ -265,6 +267,17 @@ else . = FALSE +/obj/machinery/status_display/door_timer/proc/grey_tide(datum/source, list/grey_tide_areas) + SIGNAL_HANDLER + + if(!is_station_level(z)) + return + + for(var/area_type in grey_tide_areas) + if(!istype(get_area(src), area_type)) + continue + timer_end(forced = TRUE) + #undef PRESET_SHORT #undef PRESET_MEDIUM #undef PRESET_LONG diff --git a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm index 4c8ddc347c6..9d660fc222a 100644 --- a/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm +++ b/code/game/objects/structures/crates_lockers/closets/secure/secure_closets.dm @@ -7,3 +7,19 @@ armor = list(MELEE = 30, BULLET = 50, LASER = 50, ENERGY = 100, BOMB = 0, BIO = 0, FIRE = 80, ACID = 80) secure = TRUE damage_deflection = 20 + +/obj/structure/closet/secure_closet/Initialize(mapload) + . = ..() + RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) + +/obj/structure/closet/secure_closet/proc/grey_tide(datum/source, list/grey_tide_areas) + SIGNAL_HANDLER + + if(!is_station_level(z)) + return + + for(var/area_type in grey_tide_areas) + if(!istype(get_area(src), area_type)) + continue + locked = FALSE + update_appearance(UPDATE_ICON) diff --git a/code/modules/events/grey_tide.dm b/code/modules/events/grey_tide.dm new file mode 100644 index 00000000000..abfec203dbe --- /dev/null +++ b/code/modules/events/grey_tide.dm @@ -0,0 +1,61 @@ +/datum/round_event_control/grey_tide + name = "Grey Tide" + typepath = /datum/round_event/grey_tide + max_occurrences = 2 + min_players = 5 + category = EVENT_CATEGORY_ENGINEERING + description = "Bolts open all doors in one or more departments." + +/datum/round_event_control/grey_tide/can_spawn_event(players_amt) + . = ..() + + for(var/datum/round_event/running_event in SSevents.running) + if(istype(running_event, /datum/round_event/grey_tide)) //Two of these at once messes up the list + return FALSE + +/datum/round_event/grey_tide + announce_when = 50 + end_when = 20 + ///The number of areas to be hit by the event. + var/severity = 1 + ///The area subtypes to be targeted by the event. + var/list/grey_tide_areas = list() + +/datum/round_event/grey_tide/setup() + announce_when = rand(50, 60) + end_when = rand(20, 30) + severity = rand(1,3) + + var/list/potential_areas = list(/area/station/command, + /area/station/engineering, + /area/station/medical, + /area/station/security, + /area/station/cargo, + /area/station/science, + ) + + for(var/i in 1 to severity) + grey_tide_areas += pick_n_take(potential_areas) + +/datum/round_event/grey_tide/announce(fake) + priority_announce("Gr3y.T1d3 virus detected in [station_name()] secure locking encryption subroutines. Severity level of [severity]. Recommend station AI involvement.", "Security Alert") + +/datum/round_event/grey_tide/start() + if(!length(grey_tide_areas)) + stack_trace("Could not initiate grey-tide. No areas in the list!") + kill() + +/datum/round_event/grey_tide/tick() + if(!ISMULTIPLE(activeFor, 12)) + return + + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_GREY_TIDE_LIGHT, grey_tide_areas) + +// Objects currently impacted by the greytide event: +// /obj/machinery/door/airlock -- Signal bolts open the door +// /obj/machinery/status_display/door_timer -- Signal instantly ends the timer, releasing the occupant +// /obj/structure/closet/secure_closet -- Signal unlocks locked lockers +// /obj/machinery/power/apc -- Signal turns the lighting channel off + +/datum/round_event/grey_tide/end() + SEND_GLOBAL_SIGNAL(COMSIG_GLOB_GREY_TIDE, grey_tide_areas) diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm deleted file mode 100644 index 042b06dbcbd..00000000000 --- a/code/modules/events/prison_break.dm +++ /dev/null @@ -1,60 +0,0 @@ -/datum/round_event_control/grey_tide - name = "Grey Tide" - typepath = /datum/round_event/grey_tide - max_occurrences = 2 - min_players = 5 - category = EVENT_CATEGORY_ENGINEERING - description = "Bolts open all doors in one or more departments." - -/datum/round_event/grey_tide - announce_when = 50 - end_when = 20 - var/list/area/areasToOpen = list() - var/list/potential_areas = list(/area/station/command, - /area/station/engineering, - /area/station/medical, - /area/station/security, - /area/station/cargo, - /area/station/science) - var/severity = 1 - - -/datum/round_event/grey_tide/setup() - announce_when = rand(50, 60) - end_when = rand(20, 30) - severity = rand(1,3) - for(var/i in 1 to severity) - var/picked_area = pick_n_take(potential_areas) - for(var/area/A as anything in GLOB.areas) - if(istype(A, picked_area)) - areasToOpen += A - - -/datum/round_event/grey_tide/announce(fake) - if(areasToOpen && areasToOpen.len > 0) - priority_announce("Gr3y.T1d3 virus detected in [station_name()] door subroutines. Severity level of [severity]. Recommend station AI involvement.", "Security Alert") - else - log_world("ERROR: Could not initiate grey-tide. No areas in the list!") - kill() - - -/datum/round_event/grey_tide/start() - for(var/area/A in areasToOpen) - for(var/obj/machinery/light/L in A) - L.flicker(10) - -/datum/round_event/grey_tide/end() - for(var/area/A in areasToOpen) - for(var/obj/O in A) - if(istype(O, /obj/structure/closet/secure_closet)) - var/obj/structure/closet/secure_closet/temp = O - temp.locked = FALSE - temp.update_appearance() - else if(istype(O, /obj/machinery/door/airlock)) - var/obj/machinery/door/airlock/temp = O - if(temp.critical_machine) //Skip doors in critical positions, such as the SM chamber. - continue - temp.prison_open() - else if(istype(O, /obj/machinery/status_display/door_timer)) - var/obj/machinery/status_display/door_timer/temp = O - temp.timer_end(forced = TRUE) diff --git a/code/modules/power/apc/apc_main.dm b/code/modules/power/apc/apc_main.dm index 0e6687ea01d..41c186f8974 100644 --- a/code/modules/power/apc/apc_main.dm +++ b/code/modules/power/apc/apc_main.dm @@ -186,6 +186,8 @@ if(abs(offset_old) != APC_PIXEL_OFFSET) log_mapping("APC: ([src]) at [AREACOORD(src)] with dir ([dir] | [uppertext(dir2text(dir))]) has pixel_[dir & (WEST|EAST) ? "x" : "y"] value [offset_old] - should be [dir & (SOUTH|EAST) ? "-" : ""][APC_PIXEL_OFFSET]. Use the directional/ helpers!") + RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE, PROC_REF(grey_tide)) + /obj/machinery/power/apc/Destroy() GLOB.apcs_list -= src @@ -206,6 +208,7 @@ QDEL_NULL(cell) if(terminal) disconnect_terminal() + . = ..() /obj/machinery/power/apc/handle_atom_del(atom/deleting_atom) @@ -615,6 +618,19 @@ /obj/machinery/power/apc/proc/report() return "[area.name] : [equipment]/[lighting]/[environ] ([lastused_total]) : [cell? cell.percent() : "N/C"] ([charging])" +/obj/machinery/power/apc/proc/grey_tide(datum/source, list/grey_tide_areas) + SIGNAL_HANDLER + + if(!is_station_level(z)) + return + + for(var/area_type in grey_tide_areas) + if(!istype(get_area(src), area_type)) + continue + lighting = APC_CHANNEL_OFF //Escape (or sneak in) under the cover of darkness + update_appearance(UPDATE_ICON) + update() + /*Power module, used for APC construction*/ /obj/item/electronics/apc name = "power control module" diff --git a/code/modules/power/lighting/light.dm b/code/modules/power/lighting/light.dm index 88857cd4262..6123afda2db 100644 --- a/code/modules/power/lighting/light.dm +++ b/code/modules/power/lighting/light.dm @@ -91,6 +91,9 @@ if(!start_with_cell || no_low_power) has_mock_cell = FALSE + if(is_station_level(z)) + RegisterSignal(SSdcs, COMSIG_GLOB_GREY_TIDE_LIGHT, PROC_REF(grey_tide)) //Only put the signal on station lights + RegisterSignal(src, COMSIG_LIGHT_EATER_ACT, PROC_REF(on_light_eater)) AddElement(/datum/element/atmos_sensitive, mapload) return INITIALIZE_HINT_LATELOAD @@ -676,8 +679,13 @@ tube?.burn() return +/obj/machinery/light/proc/grey_tide(datum/source, list/grey_tide_areas) + SIGNAL_HANDLER - + for(var/area_type in grey_tide_areas) + if(!istype(get_area(src), area_type)) + continue + INVOKE_ASYNC(src, PROC_REF(flicker)) /obj/machinery/light/floor name = "floor light" diff --git a/tgstation.dme b/tgstation.dme index 294b0a55aa7..fd211ea8c44 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -240,6 +240,7 @@ #include "code\__DEFINES\dcs\signals\signals_customizable.dm" #include "code\__DEFINES\dcs\signals\signals_cytology.dm" #include "code\__DEFINES\dcs\signals\signals_datum.dm" +#include "code\__DEFINES\dcs\signals\signals_event.dm" #include "code\__DEFINES\dcs\signals\signals_fish.dm" #include "code\__DEFINES\dcs\signals\signals_food.dm" #include "code\__DEFINES\dcs\signals\signals_gib.dm" @@ -3079,6 +3080,7 @@ #include "code\modules\events\fake_virus.dm" #include "code\modules\events\false_alarm.dm" #include "code\modules\events\gravity_generator_blackout.dm" +#include "code\modules\events\grey_tide.dm" #include "code\modules\events\grid_check.dm" #include "code\modules\events\heart_attack.dm" #include "code\modules\events\immovable_rod.dm" @@ -3088,7 +3090,6 @@ #include "code\modules\events\meteor_wave.dm" #include "code\modules\events\mice_migration.dm" #include "code\modules\events\portal_storm.dm" -#include "code\modules\events\prison_break.dm" #include "code\modules\events\processor_overload.dm" #include "code\modules\events\radiation_storm.dm" #include "code\modules\events\scrubber_clog.dm"