From 3fbe5d46ac9db41aabf468e8a548598d73528055 Mon Sep 17 00:00:00 2001 From: Kyep <16434066+Kyep@users.noreply.github.com> Date: Sat, 17 Oct 2020 18:04:29 +0000 Subject: [PATCH] Solar Flares (#14400) * Solar Flares * fixup * SSsun * convert solar flare to a /datum/weather * AA request * shock chance for APCs = 5% per 2.5M of power in grid * refactor * farie suggestions * farie suggestions 2 * reduced maximum length from 15m to 10m Co-authored-by: Kyep --- code/controllers/subsystem/sun.dm | 1 + code/datums/weather/weather.dm | 11 +++-- .../weather/weather_types/solar_flare.dm | 48 +++++++++++++++++++ code/modules/events/event_container.dm | 1 + code/modules/events/solarflare.dm | 10 ++++ code/modules/power/apc.dm | 9 +++- code/modules/power/solar.dm | 5 +- paradise.dme | 2 + 8 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 code/datums/weather/weather_types/solar_flare.dm create mode 100644 code/modules/events/solarflare.dm diff --git a/code/controllers/subsystem/sun.dm b/code/controllers/subsystem/sun.dm index 3f8e15df05a..fc691c3a0c0 100644 --- a/code/controllers/subsystem/sun.dm +++ b/code/controllers/subsystem/sun.dm @@ -9,6 +9,7 @@ SUBSYSTEM_DEF(sun) var/dy var/rate var/list/solars = list() + var/solar_gen_rate = 1500 /datum/controller/subsystem/sun/Initialize(start_timeofday) // Lets work out an angle for the "sun" to rotate around the station diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index 6d36b81f7b4..a4295f8aeba 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -45,10 +45,7 @@ ..() impacted_z_levels = z_levels -/datum/weather/proc/telegraph() - if(stage == STARTUP_STAGE) - return - stage = STARTUP_STAGE +/datum/weather/proc/generate_area_list() var/list/affectareas = list() for(var/V in get_areas(area_type)) affectareas += V @@ -58,6 +55,12 @@ var/area/A = V if(A.z in impacted_z_levels) impacted_areas |= A + +/datum/weather/proc/telegraph() + if(stage == STARTUP_STAGE) + return + stage = STARTUP_STAGE + generate_area_list() weather_duration = rand(weather_duration_lower, weather_duration_upper) START_PROCESSING(SSweather, src) update_areas() diff --git a/code/datums/weather/weather_types/solar_flare.dm b/code/datums/weather/weather_types/solar_flare.dm new file mode 100644 index 00000000000..97e4d82596e --- /dev/null +++ b/code/datums/weather/weather_types/solar_flare.dm @@ -0,0 +1,48 @@ +/datum/weather/solar_flare + name = "solar flare" + desc = "An intense blast of light and heat from the sun, affecting all space around the station." + + telegraph_duration = 30 SECONDS + telegraph_message = null // handled via event announcement + + weather_message = "A solar flare has arrived! Find shelter!" + weather_overlay = "light_ash" + weather_duration_lower = 5 MINUTES + weather_duration_upper = 10 MINUTES + weather_color = COLOR_YELLOW + weather_sound = 'sound/misc/bloblarm.ogg' // also used by radiation storm and SM + + end_duration = 10 // wind_down() does not do anything for this event, so we just trigger end() semi-immediately + end_message = null + area_type = /area/space // read generate_area_list() as well below + protected_areas = list() + target_trait = STATION_LEVEL + immunity_type = "burn" + +/datum/weather/solar_flare/generate_area_list() + ..() + var/list/bonus_areas = get_areas(/area/solar) + // no, solars in space are NOT a subtype of /area/space. + // no, we don't want to re-path every reference to all the subtypes of /area/solar across every map file. + // no, we don't want to change /datum/weather/var/area_type into a list as that requires changing every item that touches weather + for(var/V in bonus_areas) + var/area/A = V + if(A.z in impacted_z_levels) + impacted_areas |= A + +/datum/weather/solar_flare/start() + ..() + // Solars produce 40x as much power. 240KW becomes 9.6MW. Enough to cause APCs to arc all over the station if >=2 solars are hotwired. + SSsun.solar_gen_rate = initial(SSsun.solar_gen_rate) * 40 + +/datum/weather/solar_flare/weather_act(mob/living/L) + L.adjustFireLoss(1) + if(prob(10)) + to_chat(L, "The solar flare burns you! Seek shelter!") + +/datum/weather/solar_flare/end() + if(..()) + return + GLOB.event_announcement.Announce("The solar flare has passed.", "Solar Flare Advisory") + // Ends the temporary 40x increase that happened during the weather event + SSsun.solar_gen_rate = initial(SSsun.solar_gen_rate) diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm index 7b165f34213..65d64069cf2 100644 --- a/code/modules/events/event_container.dm +++ b/code/modules/events/event_container.dm @@ -151,6 +151,7 @@ GLOBAL_LIST_EMPTY(event_last_fired) new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 0, list(ASSIGNMENT_SECURITY = 20)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Vines", /datum/event/spacevine, 250, list(ASSIGNMENT_ENGINEER = 10)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meteor Shower", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 25)), + new /datum/event_meta(EVENT_LEVEL_MODERATE, "Solar Flare", /datum/event/solar_flare, 0, list(ASSIGNMENT_ENGINEER = 25)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Meaty Ores", /datum/event/dust/meaty, 0, list(ASSIGNMENT_ENGINEER = 20)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Communication Blackout", /datum/event/communications_blackout, 500, list(ASSIGNMENT_AI = 150, ASSIGNMENT_SECURITY = 120)), new /datum/event_meta(EVENT_LEVEL_MODERATE, "Prison Break", /datum/event/prison_break, 0, list(ASSIGNMENT_SECURITY = 100)), diff --git a/code/modules/events/solarflare.dm b/code/modules/events/solarflare.dm new file mode 100644 index 00000000000..edd1726cbb2 --- /dev/null +++ b/code/modules/events/solarflare.dm @@ -0,0 +1,10 @@ +/datum/event/solar_flare + startWhen = 2 + endWhen = 3 + announceWhen = 1 + +/datum/event/solar_flare/announce() + GLOB.event_announcement.Announce("A solar flare has been detected on collision course with the station.", "Incoming Solar Flare", 'sound/AI/attention.ogg') + +/datum/event/solar_flare/start() + SSweather.run_weather(/datum/weather/solar_flare) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index c4d3fb6cb91..df9abed6733 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1195,8 +1195,13 @@ charging = 0 chargecount = 0 - if(excess >= 5000000 && !shock_proof) //If there's more than 5,000,000 watts in the grid, start arcing and shocking people. - if(prob(5)) + if(excess >= 2500000 && !shock_proof) + var/shock_chance = 5 // 5% + if(excess >= 7500000) + shock_chance = 15 + else if(excess >= 5000000) + shock_chance = 10 + if(prob(shock_chance)) var/list/shock_mobs = list() for(var/C in view(get_turf(src), 5)) //We only want to shock a single random mob in range, not every one. if(isliving(C)) diff --git a/code/modules/power/solar.dm b/code/modules/power/solar.dm index 7bb2f16b64a..e8295eedeb2 100644 --- a/code/modules/power/solar.dm +++ b/code/modules/power/solar.dm @@ -1,5 +1,4 @@ #define SOLAR_MAX_DIST 40 -#define SOLARGENRATE 1500 /obj/machinery/power/solar name = "solar panel" @@ -131,7 +130,7 @@ if(powernet == control.powernet)//check if the panel is still connected to the computer if(obscured) //get no light from the sun, so don't generate power return - var/sgen = SOLARGENRATE * sunfrac + var/sgen = SSsun.solar_gen_rate * sunfrac add_avail(sgen) control.gen += sgen else //if we're no longer on the same powernet, remove from control computer @@ -379,7 +378,7 @@ /obj/machinery/power/solar_control/tgui_data(mob/user) var/list/data = list() data["generated"] = round(lastgen) //generated power by all connected panels - data["generated_ratio"] = data["generated"] / round(max(connected_panels.len, 1) * SOLARGENRATE) //power generation ratio. Used for the power bar + data["generated_ratio"] = data["generated"] / round(max(connected_panels.len, 1) * SSsun.solar_gen_rate) //power generation ratio. Used for the power bar data["direction"] = angle2text(cdir) //current orientation of the panels data["cdir"] = cdir //current orientation of the of the panels in degrees data["tracking_state"] = track //tracker status: TRACKER_OFF, TRACKER_TIMED, TRACKER_AUTO diff --git a/paradise.dme b/paradise.dme index 419b5332d6b..8d001f1e0ad 100644 --- a/paradise.dme +++ b/paradise.dme @@ -435,6 +435,7 @@ #include "code\datums\weather\weather_types\floor_is_lava.dm" #include "code\datums\weather\weather_types\radiation_storm.dm" #include "code\datums\weather\weather_types\snow_storm.dm" +#include "code\datums\weather\weather_types\solar_flare.dm" #include "code\datums\wires\airlock.dm" #include "code\datums\wires\alarm.dm" #include "code\datums\wires\apc.dm" @@ -1473,6 +1474,7 @@ #include "code\modules\events\rogue_drones.dm" #include "code\modules\events\sentience.dm" #include "code\modules\events\slaughterevent.dm" +#include "code\modules\events\solarflare.dm" #include "code\modules\events\spacevine.dm" #include "code\modules\events\spider_infestation.dm" #include "code\modules\events\spider_terror.dm"