Rework power outage event (#13117)

* Rework power outage event

* Added compile time flag for event fixing itself when it ends

* Review Cleanup 1

* Fixed up line ending conflicts

* Going whole hog with a side of bacon

* Whoops, forgot the sausage and Canadian Bacon

* Better messaging and makes APC Overload an offical non-random event

* Test merge feedback rework
This commit is contained in:
Patrick Meade
2020-06-05 22:41:52 -05:00
committed by GitHub
parent 03b8a297d8
commit a2ecd79be7
9 changed files with 147 additions and 91 deletions
+63
View File
@@ -0,0 +1,63 @@
#define APC_BREAK_PROBABILITY 25 // the probability that a given APC will be broken
/datum/event/apc_overload
var/const/announce_after_mc_ticks = 5
var/const/delayed = FALSE
var/const/event_max_duration_mc_ticks = announce_after_mc_ticks * 2
var/const/event_min_duration_mc_ticks = announce_after_mc_ticks
announceWhen = announce_after_mc_ticks
/datum/event/apc_overload/setup()
endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks)
/datum/event/apc_overload/start()
apc_overload_failure(announce=delayed)
var/sound/S = sound('sound/effects/powerloss.ogg')
for(var/mob/living/M in GLOB.player_list)
var/turf/T = get_turf(M)
if(!M.client || !is_station_level(T.z))
continue
SEND_SOUND(M, S)
/datum/event/apc_overload/announce()
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/apc_overload.ogg')
/datum/event/apc_overload/end()
return TRUE
/proc/apc_overload_failure(announce=TRUE)
var/list/skipped_areas_apc = list(
/area/engine/engineering,
/area/turret_protected/ai)
if(announce)
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please check all underfloor APC terminals.", "Critical Power Failure", new_sound = 'sound/AI/apc_overload.ogg')
// break APC_BREAK_PROBABILITY% of all of the APCs on the station
var/affected_apc_count = 0
for(var/obj/machinery/power/apc/C in GLOB.apcs)
// skip any APCs that are too critical to break
var/area/current_area = get_area(C)
if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
continue
// if we are going to break this one
if(prob(APC_BREAK_PROBABILITY))
// if it has a cell, drain all the charge from the cell
if(C.cell)
C.cell.charge = 0
// if it has a terminal, disconnect and delete the terminal
if(C.terminal)
var/obj/machinery/power/terminal/T = C.terminal
C.terminal.master = null
C.terminal = null
qdel(T)
// if it was operating, toggle off the breaker
if(C.operating)
C.toggle_breaker()
// no matter what, ensure the area knows something happened to the power
current_area.power_change()
affected_apc_count++
log_and_message_admins("APC Overload event deleted [affected_apc_count] underfloor APC terminals.")
#undef APC_BREAK_PROBABILITY
+78
View File
@@ -0,0 +1,78 @@
#define APC_BREAK_PROBABILITY 25 // the probability that a given APC will be disabled
/datum/event/apc_short
var/const/announce_after_mc_ticks = 5
var/const/delayed = FALSE
var/const/event_max_duration_mc_ticks = announce_after_mc_ticks * 2
var/const/event_min_duration_mc_ticks = announce_after_mc_ticks
announceWhen = announce_after_mc_ticks
/datum/event/apc_short/setup()
endWhen = rand(event_min_duration_mc_ticks, event_max_duration_mc_ticks)
/datum/event/apc_short/start()
power_failure(announce=delayed)
var/sound/S = sound('sound/effects/powerloss.ogg')
for(var/mob/living/M in GLOB.player_list)
var/turf/T = get_turf(M)
if(!M.client || !is_station_level(T.z))
continue
SEND_SOUND(M, S)
/datum/event/apc_short/announce()
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/apc_short.ogg')
/datum/event/apc_short/end()
return TRUE
/proc/power_failure(announce=TRUE)
var/list/skipped_areas_apc = list(
/area/engine/engineering,
/area/turret_protected/ai)
if(announce)
GLOB.event_announcement.Announce("Overload detected in [station_name()]'s powernet. Engineering, please repair shorted APCs.", "Systems Power Failure", new_sound = 'sound/AI/apc_short.ogg')
// break APC_BREAK_PROBABILITY% of all of the APCs on the station
var/affected_apc_count = 0
for(var/obj/machinery/power/apc/C in GLOB.apcs)
// skip any APCs that are too critical to disable
var/area/current_area = get_area(C)
if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
continue
// if we are going to break this one
if(prob(APC_BREAK_PROBABILITY))
// if it has internal wires, cut the power wires
if(C.wires)
if(!C.wires.IsIndexCut(APC_WIRE_MAIN_POWER1))
C.wires.CutWireIndex(APC_WIRE_MAIN_POWER1)
if(!C.wires.IsIndexCut(APC_WIRE_MAIN_POWER2))
C.wires.CutWireIndex(APC_WIRE_MAIN_POWER2)
// if it was operating, toggle off the breaker
if(C.operating)
C.toggle_breaker()
// no matter what, ensure the area knows something happened to the power
current_area.power_change()
affected_apc_count++
log_and_message_admins("APC Short event shorted out [affected_apc_count] APCs.")
/proc/power_restore(announce=TRUE)
power_restore_quick(announce)
/proc/power_restore_quick(announce=TRUE)
if(announce)
GLOB.event_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
// fix all of the SMESs
for(var/obj/machinery/power/smes/S in GLOB.machines)
if(!is_station_level(S.z))
continue
S.charge = S.capacity
S.output_level = S.output_level_max
S.output_attempt = 1
S.input_attempt = 1
S.update_icon()
S.power_change()
#undef APC_BREAK_PROBABILITY
+3 -2
View File
@@ -128,7 +128,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
/datum/event_container/mundane
severity = EVENT_LEVEL_MUNDANE
available_events = list(
// Severity level, event name, even type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero
// Severity level, event name, event type, base weight, role weights, one shot, min weight, max weight. Last two only used if set and non-zero
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Nothing", /datum/event/nothing, 1100),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "PDA Spam", /datum/event/pda_spam, 0, list(ASSIGNMENT_ANY = 4), 0, 25, 50),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Money Lotto", /datum/event/money_lotto, 0, list(ASSIGNMENT_ANY = 1), 1, 5, 15),
@@ -157,7 +157,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)),
//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)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Grid Check", /datum/event/grid_check, 200, list(ASSIGNMENT_ENGINEER = 60)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "APC Short", /datum/event/apc_short, 200, list(ASSIGNMENT_ENGINEER = 60)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Electrical Storm", /datum/event/electrical_storm, 250, list(ASSIGNMENT_ENGINEER = 20, ASSIGNMENT_JANITOR = 150)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Radiation Storm", /datum/event/radiation_storm, 25, list(ASSIGNMENT_MEDICAL = 50), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
@@ -191,6 +191,7 @@ GLOBAL_LIST_EMPTY(event_last_fired)
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Nothing", /datum/event/nothing, 1320),
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, "APC Overload", /datum/event/apc_overload, 0),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 5), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Abductor Visit", /datum/event/abductor, 80, is_one_shot = 1),
-82
View File
@@ -1,82 +0,0 @@
/datum/event/grid_check //NOTE: Times are measured in master controller ticks!
announceWhen = 5
/datum/event/grid_check/setup()
endWhen = rand(30,120)
/datum/event/grid_check/start()
power_failure(0)
var/sound/S = sound('sound/effects/powerloss.ogg')
for(var/mob/living/M in GLOB.player_list)
var/turf/T = get_turf(M)
if(!M.client || !is_station_level(T.z))
continue
SEND_SOUND(M, S)
/datum/event/grid_check/announce()
GLOB.event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Automated Grid Check", new_sound = 'sound/AI/poweroff.ogg')
/datum/event/grid_check/end()
power_restore()
/proc/power_failure(var/announce = 1)
if(announce)
GLOB.event_announcement.Announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", new_sound = 'sound/AI/poweroff.ogg')
var/list/skipped_areas = list(/area/turret_protected/ai)
var/list/skipped_areas_apc = list(/area/engine/engineering)
for(var/obj/machinery/power/smes/S in GLOB.machines)
var/area/current_area = get_area(S)
if((current_area.type in skipped_areas) || !is_station_level(S.z))
continue
S.last_charge = S.charge
S.last_output_attempt = S.output_attempt
S.last_input_attempt = S.input_attempt
S.charge = 0
S.inputting(0)
S.outputting(0)
S.update_icon()
S.power_change()
for(var/obj/machinery/power/apc/C in GLOB.apcs)
var/area/current_area = get_area(C)
if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
continue
if(C.cell)
C.cell.charge = 0
/proc/power_restore(var/announce = 1)
var/list/skipped_areas = list(/area/turret_protected/ai)
var/list/skipped_areas_apc = list(/area/engine/engineering)
if(announce)
GLOB.event_announcement.Announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
for(var/obj/machinery/power/apc/C in GLOB.apcs)
var/area/current_area = get_area(C)
if((current_area.type in skipped_areas_apc) || !is_station_level(C.z))
continue
if(C.cell)
C.cell.charge = C.cell.maxcharge
for(var/obj/machinery/power/smes/S in GLOB.machines)
var/area/current_area = get_area(S)
if((current_area.type in skipped_areas) || !is_station_level(S.z))
continue
S.charge = S.last_charge
S.output_attempt = S.last_output_attempt
S.input_attempt = S.last_input_attempt
S.update_icon()
S.power_change()
/proc/power_restore_quick(var/announce = 1)
if(announce)
GLOB.event_announcement.Announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", new_sound = 'sound/AI/poweron.ogg')
for(var/obj/machinery/power/smes/S in GLOB.machines)
if(!is_station_level(S.z))
continue
S.charge = S.capacity
S.output_level = S.output_level_max
S.output_attempt = 1
S.input_attempt = 1
S.update_icon()
S.power_change()
+1 -1
View File
@@ -244,7 +244,7 @@
else if(has_electronics && !terminal)
. += "Electronics installed but not wired."
else /* if(!has_electronics && !terminal) */
. += "There is no electronics nor connected wires."
. += "There are no electronics nor connected wires."
else
if(stat & MAINT)
. += "The cover is closed. Something wrong with it: it doesn't work."
-5
View File
@@ -29,11 +29,6 @@
var/output_level_max = 200000 // cap on output_level
var/output_used = 0 // amount of power actually outputted. may be less than output_level if the powernet returns excess power
//Holders for powerout event.
var/last_output_attempt = 0
var/last_input_attempt = 0
var/last_charge = 0
var/name_tag = null
var/obj/machinery/power/terminal/terminal = null