diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index ccca11387dd..51ce05309ca 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -395,12 +395,8 @@ return pick(possible_loc) -///Prevents power_failure message spam if a traitor purchases repeatedly. -GLOBAL_VAR_INIT(power_failure_message_cooldown, 0) - ///Disable power in the station APCs /proc/power_fail(duration_min, duration_max) - var/message_cooldown for(var/obj/machinery/power/apc/current_apc as anything in GLOB.apcs_list) if(!current_apc.cell || !SSmapping.level_trait(current_apc.z, ZTRAIT_STATION)) continue @@ -409,9 +405,7 @@ GLOBAL_VAR_INIT(power_failure_message_cooldown, 0) continue var/duration = rand(duration_min,duration_max) - message_cooldown = max(duration, message_cooldown) current_apc.energy_fail(duration) - GLOB.power_failure_message_cooldown = world.time + message_cooldown /** * Sends a round tip to a target. If selected_tip is null, a random tip will be sent instead (5% chance of it being silly). diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index 2829acccb82..6819805c0c6 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -1,6 +1,13 @@ +/** + * Causes a power failure across the station. + * + * All SMESs and APCs will be fully drained, and all areas will power down. + * + * The drain is permanent (that is, it won't automatically come back after some time like the grid check event), + * but the crew themselves can return power via the engine, solars, or other means of creating power. + */ /proc/power_failure() - if(GLOB.power_failure_message_cooldown > world.time) - priority_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", ANNOUNCER_POWEROFF) + priority_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", ANNOUNCER_POWEROFF) for(var/obj/machinery/power/smes/S in GLOB.machines) if(istype(get_area(S), /area/station/ai_monitored/turret_protected) || !is_station_level(S.z)) continue @@ -10,16 +17,18 @@ S.update_appearance() S.power_change() - for(var/area/A as anything in GLOB.the_station_areas) - if(!A.requires_power || A.always_unpowered ) + for(var/area/station_area as anything in GLOB.areas) + if(!station_area.z || !is_station_level(station_area.z)) continue - if(GLOB.typecache_powerfailure_safe_areas[A.type]) + if(!station_area.requires_power || station_area.always_unpowered ) + continue + if(GLOB.typecache_powerfailure_safe_areas[station_area.type]) continue - A.power_light = FALSE - A.power_equip = FALSE - A.power_environ = FALSE - A.power_change() + station_area.power_light = FALSE + station_area.power_equip = FALSE + station_area.power_environ = FALSE + station_area.power_change() for(var/obj/machinery/power/apc/C in GLOB.apcs_list) if(C.cell && is_station_level(C.z)) @@ -29,6 +38,11 @@ C.cell.charge = 0 +/** + * Restores power to all rooms on the station. + * + * Magically fills ALL APCs and SMESs to capacity, and restores power to depowered areas. + */ /proc/power_restore() priority_announce("Power has been restored to [station_name()]. We apologize for the inconvenience.", "Power Systems Nominal", ANNOUNCER_POWERON) for(var/obj/machinery/power/apc/C in GLOB.apcs_list) @@ -43,17 +57,27 @@ S.output_attempt = TRUE S.update_appearance() S.power_change() - for(var/area/A in GLOB.the_station_areas) - if(!A.requires_power || A.always_unpowered) + for(var/area/station_area as anything in GLOB.areas) + if(!station_area.z || !is_station_level(station_area.z)) continue - if(!istype(A, /area/shuttle)) - A.power_light = TRUE - A.power_equip = TRUE - A.power_environ = TRUE - A.power_change() + if(!station_area.requires_power || station_area.always_unpowered) + continue + if(istype(station_area, /area/shuttle)) + continue + station_area.power_light = TRUE + station_area.power_equip = TRUE + station_area.power_environ = TRUE + station_area.power_change() +/** + * A quicker version of [/proc/power_restore] that only handles recharging SMESs. + * + * This will also repower an entire station - it is not instantaneous like power restore, + * but it is faster performance-wise as it only handles SMES units. + * + * Great as a less magical / more IC way to return power to a sapped station. + */ /proc/power_restore_quick() - priority_announce("All SMESs on [station_name()] have been recharged. We apologize for the inconvenience.", "Power Systems Nominal", ANNOUNCER_POWERON) for(var/obj/machinery/power/smes/S in GLOB.machines) if(!is_station_level(S.z)) diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm index 143d36ed40f..7752ddfab0e 100644 --- a/code/modules/events/grid_check.dm +++ b/code/modules/events/grid_check.dm @@ -5,14 +5,21 @@ max_occurrences = 3 category = EVENT_CATEGORY_ENGINEERING description = "Turns off all APCs for a while, or until they are manually rebooted." + /// Cooldown for the announement associated with this event. + /// Necessary due to the fact that this event is player triggerable. + COOLDOWN_DECLARE(announcement_spam_protection) /datum/round_event/grid_check announce_when = 1 start_when = 1 /datum/round_event/grid_check/announce(fake) - if(fake || (GLOB.power_failure_message_cooldown > world.time)) - priority_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", ANNOUNCER_POWEROFF) + var/datum/round_event_control/grid_check/controller = control + if(!COOLDOWN_FINISHED(controller, announcement_spam_protection) && !fake) + return + priority_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", ANNOUNCER_POWEROFF) + if(!fake) // Only start the CD if we're real + COOLDOWN_START(controller, announcement_spam_protection, 30 SECONDS) /datum/round_event/grid_check/start() power_fail(30, 120)