diff --git a/code/game/area/Space Station 13 areas.dm b/code/game/area/Space Station 13 areas.dm
index 21e965244b..c0c8b4883b 100755
--- a/code/game/area/Space Station 13 areas.dm
+++ b/code/game/area/Space Station 13 areas.dm
@@ -1353,10 +1353,24 @@ area/space/atmosalert()
/area/security/brig
name = "\improper Security - Brig"
icon_state = "brig"
+ prison_break()
+ for(var/obj/structure/closet/secure_closet/brig/temp_closet in src)
+ temp_closet.locked = 0
+ temp_closet.icon_state = temp_closet.icon_closed
+ for(var/obj/machinery/door_timer/temp_timer in src)
+ temp_timer.releasetime = 1
+ ..()
/area/security/prison
name = "\improper Security - Prison Wing"
icon_state = "sec_prison"
+ prison_break()
+ for(var/obj/structure/closet/secure_closet/brig/temp_closet in src)
+ temp_closet.locked = 0
+ temp_closet.icon_state = temp_closet.icon_closed
+ for(var/obj/machinery/door_timer/temp_timer in src)
+ temp_timer.releasetime = 1
+ ..()
/area/security/warden
name = "\improper Security - Warden's Office"
diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm
index 38452c3d5b..dccc9e9dbf 100644
--- a/code/game/area/areas.dm
+++ b/code/game/area/areas.dm
@@ -293,3 +293,10 @@ var/list/mob/living/forced_ambiance_list = new
H.AdjustWeakened(1)
mob << "The sudden appearance of gravity makes you fall to the floor!"
+/area/proc/prison_break()
+ for(var/obj/machinery/power/apc/temp_apc in src)
+ temp_apc.overload_lighting(70)
+ 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()
\ No newline at end of file
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index 2211fced44..bc2a0f7b68 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1063,7 +1063,8 @@ About the new airlock wires panel:
update_icon()
/obj/machinery/door/airlock/proc/prison_open()
- src.unlock()
- src.open()
- src.lock()
+ if(arePowerSystemsOn())
+ src.unlock()
+ src.open()
+ src.lock()
return
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index 5cb256e500..3c1aeba23f 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -161,6 +161,8 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 30, list(ASSIGNMENT_ENGINEER = 5)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 100)),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENCE = 100)),
)
/datum/event_container/major
@@ -169,6 +171,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 60), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Carp Migration", /datum/event/carp_migration, 0, list(ASSIGNMENT_SECURITY = 3), 1),
+ new /datum/event_meta(EVENT_LEVEL_MAJOR, "Containment Breach", /datum/event/prison_break/station, 0, list(ASSIGNMENT_ANY = 5)),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Space Vines", /datum/event/spacevine, 0, list(ASSIGNMENT_ENGINEER = 15), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm
index 8eb3bc5390..329cbc3e3a 100644
--- a/code/modules/events/prison_break.dm
+++ b/code/modules/events/prison_break.dm
@@ -1,52 +1,85 @@
/datum/event/prison_break
- announceWhen = 50
+ startWhen = 5
+ announceWhen = 75
- var/releaseWhen = 25
- var/list/area/prisonAreas = list()
+ var/releaseWhen = 60
+ var/list/area/areas = list() //List of areas to affect.
+
+ var/eventDept = "Security" //Department name in announcement
+ var/list/areaName = list("Brig") //Picks which types of areas are used in start()
+ var/list/areaType = list(/area/security/prison, /area/security/brig)
+ var/list/areaNotType = list() //Area types to specifically exclude.
+
+/datum/event/prison_break/virology
+ eventDept = "Medical"
+ areaName = list("Virology")
+ areaType = list(/area/medical/virology, /area/medical/virologyaccess)
+
+/datum/event/prison_break/xenobiology
+ eventDept = "Science"
+ areaName = list("Xenobiology")
+ areaType = list(/area/rnd/xenobiology)
+ areaNotType = list(/area/rnd/xenobiology/xenoflora, /area/rnd/xenobiology/xenoflora_storage)
+
+/datum/event/prison_break/station
+ eventDept = "Station"
+ areaName = list("Brig","Virology","Xenobiology")
+ areaType = list(/area/security/prison, /area/security/brig, /area/medical/virology, /area/medical/virologyaccess, /area/rnd/xenobiology)
+ areaNotType = list(/area/rnd/xenobiology/xenoflora, /area/rnd/xenobiology/xenoflora_storage)
/datum/event/prison_break/setup()
- announceWhen = rand(50, 60)
- releaseWhen = rand(20, 30)
+ announceWhen = rand(75, 105)
+ releaseWhen = rand(60, 90)
- src.startWhen = src.releaseWhen-1
- src.endWhen = src.releaseWhen+1
+ src.endWhen = src.releaseWhen+2
/datum/event/prison_break/announce()
- if(prisonAreas && prisonAreas.len > 0)
- command_announcement.Announce("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] imprisonment subroutines. Recommend station AI involvement.", "Security Alert")
- else
- world.log << "ERROR: Could not initate grey-tide. Unable find prison or brig area."
- kill()
+ if(areas && areas.len > 0)
+ command_announcement.Announce("[pick("Gr3y.T1d3 virus","Malignant trojan")] detected in [station_name()] [(eventDept == "Security")? "imprisonment":"containment"] subroutines. Secure any compromised areas immediately. Station AI involvement is recommended.", "[eventDept] Alert")
/datum/event/prison_break/start()
for(var/area/A in world)
- if(istype(A, /area/security/prison) || istype(A, /area/security/brig))
- prisonAreas += A
+ if(is_type_in_list(A,areaType) && !is_type_in_list(A,areaNotType))
+ areas += A
+ if(areas && areas.len > 0)
+ var/pass = 0
+ var/my_department = "[station_name()] firewall subroutines"
+ var/rc_message = "An unknown malicious program has been detected in the [english_list(areaName)] lighting and airlock control systems at [worldtime2text()]. Systems will be fully compromised within approximately three minutes. Direct intervention is required immediately.
"
+ for(var/obj/machinery/message_server/MS in world)
+ MS.send_rc_message("Engineering", my_department, rc_message, "", "", 2)
+ pass = 1
+ if(pass) //This entire block should be handled by send_rc_message(). I'm not rewriting it.
+ var/sending = rc_message + "Message dispatched by [my_department]."
+ for (var/obj/machinery/requests_console/Console in allConsoles)
+ var/keyed_department = ckey(Console.department)
+ if(keyed_department == ckey("Engineering"))
+ if(Console.newmessagepriority < 2)
+ Console.newmessagepriority = 2
+ Console.icon_state = "req_comp2"
+ if(!Console.silent)
+ playsound(Console.loc, 'sound/machines/twobeep.ogg', 50, 1)
+ for (var/mob/O in hearers(5, Console.loc))
+ O.show_message(text("\icon[Console] *The Requests Console beeps: 'PRIORITY Alert in [my_department]'"))
+ Console.messages += "High Priority message from [my_department]
[sending]"
+
+ for(var/mob/living/silicon/ai/A in player_list)
+ A << "Malicious program detected in the [english_list(areaName)] lighting and airlock control systems by [my_department]."
+ else
+ world.log << "ERROR: Could not initate grey-tide. Unable to find suitable containment area."
+ kill()
- if(prisonAreas && prisonAreas.len > 0)
- for(var/area/A in prisonAreas)
- for(var/obj/machinery/light/L in A)
- L.flicker(10)
/datum/event/prison_break/tick()
if(activeFor == releaseWhen)
- if(prisonAreas && prisonAreas.len > 0)
- for(var/area/A in prisonAreas)
- for(var/obj/machinery/power/apc/temp_apc in A)
- temp_apc.overload_lighting()
+ if(areas && areas.len > 0)
+ for(var/area/A in areas)
+ for(var/obj/machinery/light/L in A)
+ L.flicker(10)
- for(var/obj/structure/closet/secure_closet/brig/temp_closet in A)
- temp_closet.locked = 0
- temp_closet.icon_state = temp_closet.icon_closed
- for(var/obj/machinery/door/airlock/security/temp_airlock in A)
- temp_airlock.prison_open()
-
- for(var/obj/machinery/door/airlock/glass_security/temp_glassairlock in A)
- temp_glassairlock.prison_open()
-
- for(var/obj/machinery/door_timer/temp_timer in A)
- temp_timer.releasetime = 1
\ No newline at end of file
+/datum/event/prison_break/end()
+ for(var/area/A in shuffle(areas))
+ A.prison_break()
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index 34f3525191..29153f5a45 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -1252,17 +1252,18 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on)
update_icon()
update()
-// overload all the lights in this APC area
+// overload the lights in this APC area
-/obj/machinery/power/apc/proc/overload_lighting()
+/obj/machinery/power/apc/proc/overload_lighting(var/chance = 100)
if(/* !get_connection() || */ !operating || shorted)
return
if( cell && cell.charge>=20)
cell.use(20);
spawn(0)
for(var/obj/machinery/light/L in area)
- L.on = 1
- L.broken()
+ if(prob(chance))
+ L.on = 1
+ L.broken()
sleep(1)
/obj/machinery/power/apc/proc/setsubsystem(val)