From 3ee47475027bed749901edbb8456887dbefc71d5 Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Tue, 28 Apr 2020 02:49:09 +0200 Subject: [PATCH 1/2] Supermatter delamination tweaks - In short, delamination changed to more or less mirror effects it has on Bay. - All of the new delamination effects can be easily tweaked in the future using set of defines. - In general, aim is to make supermatter delamination a more or less "recoverable" event with enough materials and manpower. Before it was just a mangled irrepairable mess of scuttled steel. - This brings a LOT of performance improvements and runtime error fixes (grav pull of anchored items which were never meant to move tends to cause runtimes) Detailed changes: - Supermatter (and also S5/S6 singularity in the event someone manages to build one, they share the proc) no longer pull anchored items. This brings a MASSIVE reduction in delamination lag (from few second freezes to quite smooth) and prevents things from breaking (i saw dozens of various runtimes when delamination occured as it forcibly dragged things around that weren't supposed to be dragged). - Delamination crashes the station's power grid, shutting down all APCs for few minutes. Critical areas get shut down only for fraction of that time (we don't want to one-hit the AI). This includes healthcare facilities, which are likely to be very important given the other effects. - Delamination irradiates and briefly weakens all mobs on the station (not only on the same Z level). I have verified that this is enough to kill an unprotected human if no kind of medical care (at least dylovene, ideally something against rads) is administered. - Delamination will break a bunch of lights. Nuisance, but easily repairable. Adds to the atmosphere. - Delamination breaks part of the solar arrays, reducing their output by roughly 60%. This is way less than required to run the station. Puts more emphasis on delamination being engineering-centric emergency, with power rationing being a necessity until solars can be fixed, or other power source secured. Rewards engineering if they managed to stockpile some energy in the SMESes around the station. - Delamination's explosion is quite weaker than it used to be. It should still be enough to pretty much destroy the engine room (see attached screenshots below), and cause some minor damage in adjacent rooms. It should still, however, be repairable with enough resources and some time. - Supermatter no longer has additional 99% flat modifier to miss a station Z level when ejected. Emergency core ejection is a last resort measure. It does have its risks. With other changes in this PR, delamination on outer hull is significantly less dangerous than it would be before. It still has various secondary risks, however, such as the radiation or temporary power outage, but with considerably mitigated damage (explosion in space, mostly on outer grilles is generally weaker) Screenshots: https://i.imgur.com/K7nBd8a.png (Standing directly where the core was. Engine room has heavy structural damage and all pipes/machinery are pretty much devastated) https://i.imgur.com/SGBdTRo.png (Standing in engine control room. Damage nearby is quite minor (occassional snapped wire or wall panel), but quite widespread). https://i.imgur.com/JqzF4pW.png (Solar arrays are heavily damaged. They still provide /some/ power but only a fraction of the original) --- code/modules/power/singularity/act.dm | 57 +++--------- code/modules/power/supermatter/supermatter.dm | 93 ++++++++++++------- html/changelogs/atlantiscze-sm.yml | 6 ++ 3 files changed, 80 insertions(+), 76 deletions(-) create mode 100644 html/changelogs/atlantiscze-sm.yml diff --git a/code/modules/power/singularity/act.dm b/code/modules/power/singularity/act.dm index f337d3dbd4..6c2e8ca5ce 100644 --- a/code/modules/power/singularity/act.dm +++ b/code/modules/power/singularity/act.dm @@ -47,12 +47,19 @@ return 2 /obj/singularity_pull(S, current_size) - if(simulated) - if(anchored) - if(current_size >= STAGE_FIVE) - step_towards(src, S) - else - step_towards(src, S) + set waitfor = 0 + + if(anchored) + return + + sleep(0) //this is needed or multiple items will be thrown sequentially and not simultaneously + if(current_size >= STAGE_FOUR) + step_towards(src,S) + sleep(1) + step_towards(src,S) + else if(current_size > STAGE_ONE) + step_towards(src,S) + else ..() /obj/effect/beam/singularity_pull() return @@ -60,20 +67,6 @@ /obj/effect/overlay/singularity_pull() return -/obj/item/singularity_pull(S, current_size) - spawn(0) //this is needed or multiple items will be thrown sequentially and not simultaneously - if(current_size >= STAGE_FOUR) - //throw_at(S, 14, 3) - step_towards(src,S) - sleep(1) - step_towards(src,S) - else if(current_size > STAGE_ONE) - step_towards(src,S) - else ..() - -/obj/machinery/atmospherics/pipe/singularity_pull() - return - /obj/machinery/power/supermatter/shard/singularity_act() qdel(src) return 5000 @@ -113,30 +106,6 @@ ChangeTurf(get_base_turf_by_area(src)) return 2 -/turf/simulated/floor/singularity_pull(S, current_size) - if(flooring && current_size >= STAGE_THREE) - if(prob(current_size / 2)) - var/leave_tile = TRUE - if(broken || burnt || flooring.flags & TURF_IS_FRAGILE) - leave_tile = FALSE - playsound(src, 'sound/items/crowbar.ogg', 50, 1) - make_plating(leave_tile) - -/turf/simulated/wall/singularity_pull(S, current_size) - - if(!reinf_material) - if(current_size >= STAGE_FIVE) - if(prob(75)) - dismantle_wall() - return - if(current_size == STAGE_FOUR) - if(prob(30)) - dismantle_wall() - else - if(current_size >= STAGE_FIVE) - if(prob(30)) - dismantle_wall() - /turf/space/singularity_act() return diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index c0850628d6..2ef36e8b22 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -25,10 +25,17 @@ // Base variants are applied to everyone on the same Z level // Range variants are applied on per-range basis: numbers here are on point blank, it scales with the map size (assumes square shaped Z levels) -#define DETONATION_RADS 20 -#define DETONATION_HALLUCINATION_BASE 300 -#define DETONATION_HALLUCINATION_RANGE 300 -#define DETONATION_HALLUCINATION 600 +#define DETONATION_RADS 40 +#define DETONATION_MOB_CONCUSSION 4 // Value that will be used for Weaken() for mobs. + +// Base amount of ticks for which a specific type of machine will be offline for. +- 20% added by RNG. +// This does pretty much the same thing as an electrical storm, it just affects the whole Z level instantly. +#define DETONATION_APC_OVERLOAD_PROB 10 // prob() of overloading an APC's lights. +#define DETONATION_SHUTDOWN_APC 120 // Regular APC. +#define DETONATION_SHUTDOWN_CRITAPC 10 // Critical APC. AI core and such. Considerably shorter as we don't want to kill the AI with a single blast. Still a nuisance. +#define DETONATION_SHUTDOWN_SMES 60 // SMES +#define DETONATION_SHUTDOWN_RNG_FACTOR 20 // RNG factor. Above shutdown times can be +- X%, where this setting is the percent. Do not set to 100 or more. +#define DETONATION_SOLAR_BREAK_CHANCE 60 // prob() of breaking solar arrays (this is per-panel, and only affects the Z level SM is on) #define WARNING_DELAY 20 //seconds between warnings. @@ -142,29 +149,65 @@ /obj/machinery/power/supermatter/proc/explode() + + set waitfor = 0 + message_admins("Supermatter exploded at ([x],[y],[z] - JMP)",0,1) log_game("SUPERMATTER([x],[y],[z]) Exploded. Power:[power], Oxygen:[oxygen], Damage:[damage], Integrity:[get_integrity()]") anchored = 1 grav_pulling = 1 exploded = 1 - var/turf/TS = get_turf(src) // The turf supermatter is on. SM being in a locker, mecha, or other container shouldn't block it's effects that way. - if(!TS) + sleep(pull_time) + var/turf/TS = get_turf(src) // The turf supermatter is on. SM being in a locker, exosuit, or other container shouldn't block it's effects that way. + if(!istype(TS)) return - for(var/z in GetConnectedZlevels(TS.z)) + + var/list/affected_z = GetConnectedZlevels(TS.z) + + // Effect 1: Radiation, weakening to all mobs on Z level + for(var/z in affected_z) SSradiation.z_radiate(locate(1, 1, z), DETONATION_RADS, 1) + for(var/mob/living/mob in living_mob_list) - var/turf/T = get_turf(mob) - if(T && (loc.z == T.z)) - if(istype(mob, /mob/living/carbon/human)) - //Hilariously enough, running into a closet should make you get hit the hardest. - var/mob/living/carbon/human/H = mob - H.hallucination += max(50, min(300, DETONATION_HALLUCINATION * sqrt(1 / (get_dist(mob, src) + 1)) ) ) - spawn(pull_time) - explosion(get_turf(src), explosion_power, explosion_power * 2, explosion_power * 3, explosion_power * 4, 1) - spawn(5) //to allow the explosion to finish - new /obj/item/broken_sm(TS) + var/turf/TM = get_turf(mob) + if(!TM) + continue + if(!(TM.z in affected_z)) + continue + + mob.Weaken(DETONATION_MOB_CONCUSSION) + to_chat(mob, "An invisible force slams you against the ground!") + + // Effect 2: Z-level wide electrical pulse + for(var/obj/machinery/power/apc/A in machines) + if(!(A.z in affected_z)) + continue + + // Overloads lights + if(prob(DETONATION_APC_OVERLOAD_PROB)) + A.overload_lighting() + // Causes the APCs to go into system failure mode. + var/random_change = rand(100 - DETONATION_SHUTDOWN_RNG_FACTOR, 100 + DETONATION_SHUTDOWN_RNG_FACTOR) / 100 + if(A.is_critical) + A.energy_fail(round(DETONATION_SHUTDOWN_CRITAPC * random_change)) + else + A.energy_fail(round(DETONATION_SHUTDOWN_APC * random_change)) + + // Effect 3: Break solar arrays + for(var/obj/machinery/power/solar/S in machines) + if(!(S.z in affected_z)) + continue + if(prob(DETONATION_SOLAR_BREAK_CHANCE)) + S.health = -1 + S.broken() + + // Effect 4: Medium scale explosion + spawn(0) + explosion(TS, explosion_power/2, explosion_power, explosion_power * 2, explosion_power * 4, 1) qdel(src) - return + // Allow the explosion to finish + spawn(5) + new /obj/item/broken_sm(TS) //Changes color and luminosity of the light to these values if they were not already set /obj/machinery/power/supermatter/proc/shift_light(var/lum, var/clr) @@ -211,20 +254,6 @@ global_announcer.autosay(alert_msg, "Supermatter Monitor") public_alert = 0 - -/obj/machinery/power/supermatter/get_transit_zlevel() - //don't send it back to the station -- most of the time - if(prob(99)) - var/list/candidates = using_map.accessible_z_levels.Copy() - for(var/zlevel in using_map.station_levels) - candidates.Remove("[zlevel]") - candidates.Remove("[src.z]") - - if(candidates.len) - return text2num(pickweight(candidates)) - - return ..() - /obj/machinery/power/supermatter/process() var/turf/L = loc diff --git a/html/changelogs/atlantiscze-sm.yml b/html/changelogs/atlantiscze-sm.yml new file mode 100644 index 0000000000..d6d8ddbfcf --- /dev/null +++ b/html/changelogs/atlantiscze-sm.yml @@ -0,0 +1,6 @@ +author: atlantiscze + +delete-after: True + +changes: + - tweak: "Supermatter delamination effects have been tweaked. Delamination is considerably less laggy, and less directly destructive. Instead, it causes larger health hazard and secondary engineering problems such as power outage or partial damage of solar arrays." \ No newline at end of file From 2d50c71553f8ec48cb6580d99f04698db00b276c Mon Sep 17 00:00:00 2001 From: Atlantiscze Date: Sun, 3 May 2020 22:56:50 +0200 Subject: [PATCH 2/2] Buffs devastation and heavy damage ranges when supermatter is energised (up to 2x at very high power levels). - Intentionally leaving light damage range lower as at high power levels to somewhat concentrate the damage in engineering. --- code/modules/power/supermatter/supermatter.dm | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm index 2ef36e8b22..96194104b8 100644 --- a/code/modules/power/supermatter/supermatter.dm +++ b/code/modules/power/supermatter/supermatter.dm @@ -37,6 +37,9 @@ #define DETONATION_SHUTDOWN_RNG_FACTOR 20 // RNG factor. Above shutdown times can be +- X%, where this setting is the percent. Do not set to 100 or more. #define DETONATION_SOLAR_BREAK_CHANCE 60 // prob() of breaking solar arrays (this is per-panel, and only affects the Z level SM is on) +// If power level is between these two, explosion strength will be scaled accordingly between min_explosion_power and max_explosion_power +#define DETONATION_EXPLODE_MIN_POWER 200 // If power level is this or lower, minimal detonation strength will be used +#define DETONATION_EXPLODE_MAX_POWER 2000 // If power level is this or higher maximal detonation strength will be used #define WARNING_DELAY 20 //seconds between warnings. @@ -72,7 +75,8 @@ var/pull_radius = 14 // Time in ticks between delamination ('exploding') and exploding (as in the actual boom) var/pull_time = 100 - var/explosion_power = 8 + var/min_explosion_power = 8 + var/max_explosion_power = 16 var/emergency_issued = 0 @@ -203,7 +207,13 @@ // Effect 4: Medium scale explosion spawn(0) - explosion(TS, explosion_power/2, explosion_power, explosion_power * 2, explosion_power * 4, 1) + var/explosion_power = min_explosion_power + if(power > 0) + // 0-100% where 0% is at DETONATION_EXPLODE_MIN_POWER or lower and 100% is at DETONATION_EXPLODE_MAX_POWER or higher + var/strength_percentage = between(0, (power - DETONATION_EXPLODE_MIN_POWER) / ((DETONATION_EXPLODE_MAX_POWER - DETONATION_EXPLODE_MIN_POWER) / 100), 100) + explosion_power = between(min_explosion_power, (((max_explosion_power - min_explosion_power) * (strength_percentage / 100)) + min_explosion_power), max_explosion_power) + + explosion(TS, explosion_power/2, explosion_power, max_explosion_power, explosion_power * 4, 1) qdel(src) // Allow the explosion to finish spawn(5) @@ -494,7 +504,8 @@ pull_radius = 5 pull_time = 45 - explosion_power = 3 + min_explosion_power = 3 + max_explosion_power = 6 /obj/machinery/power/supermatter/shard/announce_warning() //Shards don't get announcements return