From 2a778cd510c8d0a4da13c07fd54477e377cbf596 Mon Sep 17 00:00:00 2001 From: necromanceranne <40847847+necromanceranne@users.noreply.github.com> Date: Fri, 8 Aug 2025 03:47:35 +1000 Subject: [PATCH] Changes flux anomalies and gravity anomalies to be a little less horrible to deal with. (#92216) ## About The Pull Request Flux anomalies, when they detonate, do a minor explosion and emit a wide EMP pulse. This can cause a lot of damage in its own right, but it won't syndicate bomb a random section of the station anymore. Gravity anomalies A) No longer have the click catching giant image floating above it anymore. B) No longer chain hardstuns you if you get too close every time it ticks. Instead, it knocks you down. You can also avoid this effect by wearing magboots. C) Also doesn't throw literally every object in an area around it straight into you every time it ticks. Instead, it does so only 20% of the time. Long range gas analyzers can now scan anomalies. ## Why It's Good For The Game > Flux A really annoying anomaly and one that I think has caused several shuttle calls in its time. If you don't catch it, it blows up a segment of the station entirely at random. This thing can almost be as bad as a vortex in some contexts. A giant EMP can still be pretty destructive, but it isn't quite at the same level as a giant explosion and I suspect not shuttle call worthy. The minor explosion will at most trash a room. > Gravity I literally do not understand how anyone was supposed to disable these. I literally gave up years ago even trying to catch them. They're practically designed to kill you for trying. The click catching warp effect not only looked kind of lame, but it just straight up stopped you being able to disable them (mouse opacity doesn't work here and I tried, it redirects clicks to other tiles for some godawful reason, probably byond weirdness). You had to spam click a LOT to even try. On top of that, it just stuns you? It literally just stuns you if you approach it? And magboots can't help you to avoid that? What the fuck are you _supposed_ to do to avoid that? Also it can just instantly kill you if you approach it and it gathered enough stuff because it will just keep slapping you with every loose object within a radius around itself? At speed 5 so things that don't normally embed will embed? So it mulches you for approaching it, chain hardstuns you for approaching it, and it deliberately intercepts clicks in a completely unintuitive fashion even if you do manage to click it. You need to approach it to stop it. A recipe for disaster. Fuck that. > Analyzer It was annoying this wasn't able to do this already! ## Changelog :cl: balance: Gravity anomalies can be properly clicked. Rather than chain stunning you, the anomaly will knock you down. You can avoid the negatives of gravity anomalies by wearing magboots. (Yes, it did not really protect you until now) balance: Flux anomalies detonate in a much smaller explosion, but release a wide EMP as well. balance: Long range gas analyzers can now scan anomalies. /:cl: (cherry picked from commit 2b0a8241322e2b7ef114d4747bd2afac21af925a) --- code/__DEFINES/research/anomalies.dm | 6 +- .../effects/anomalies/anomalies_flux.dm | 24 +++--- .../effects/anomalies/anomalies_gravity.dm | 83 ++----------------- .../items/devices/scanners/gas_analyzer.dm | 4 + .../supermatter/supermatter_extra_effects.dm | 2 +- 5 files changed, 30 insertions(+), 89 deletions(-) diff --git a/code/__DEFINES/research/anomalies.dm b/code/__DEFINES/research/anomalies.dm index 4ecd01e4db1..bd7380f199d 100644 --- a/code/__DEFINES/research/anomalies.dm +++ b/code/__DEFINES/research/anomalies.dm @@ -10,9 +10,9 @@ #define MAX_CORES_ECTOPLASMIC 8 ///Defines for the different types of explosion a flux anomaly can have -#define FLUX_NO_EXPLOSION 0 -#define FLUX_EXPLOSIVE 1 -#define FLUX_LOW_EXPLOSIVE 2 +#define FLUX_NO_EMP 0 +#define FLUX_EMP 1 +#define FLUX_LIGHT_EMP 2 /// Chance of anomalies moving every process tick #define ANOMALY_MOVECHANCE 45 diff --git a/code/game/objects/effects/anomalies/anomalies_flux.dm b/code/game/objects/effects/anomalies/anomalies_flux.dm index a2dc2473600..1d823d00b60 100644 --- a/code/game/objects/effects/anomalies/anomalies_flux.dm +++ b/code/game/objects/effects/anomalies/anomalies_flux.dm @@ -5,11 +5,11 @@ anomaly_core = /obj/item/assembly/signaler/anomaly/flux var/canshock = FALSE var/shockdamage = 20 - var/explosive = FLUX_EXPLOSIVE + var/emp_zap = FLUX_EMP -/obj/effect/anomaly/flux/Initialize(mapload, new_lifespan, explosive = FLUX_EXPLOSIVE) +/obj/effect/anomaly/flux/Initialize(mapload, new_lifespan, emp_zap = FLUX_EMP) . = ..() - src.explosive = explosive + src.emp_zap = emp_zap var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = PROC_REF(on_entered), ) @@ -42,20 +42,22 @@ M.electrocute_act(shockdamage, name, flags = SHOCK_NOGLOVES) /obj/effect/anomaly/flux/detonate() - switch(explosive) - if(FLUX_EXPLOSIVE) - explosion(src, devastation_range = 1, heavy_impact_range = 4, light_impact_range = 16, flash_range = 18) //Low devastation, but hits a lot of stuff. - if(FLUX_LOW_EXPLOSIVE) - explosion(src, heavy_impact_range = 1, light_impact_range = 4, flash_range = 6) - if(FLUX_NO_EXPLOSION) + switch(emp_zap) + if(FLUX_EMP) + empulse(src, 4, 16) + explosion(src, heavy_impact_range = 1, light_impact_range = 4, flash_range = 6) //Trashes the room a bit, might blow a small hole in the hull. + if(FLUX_LIGHT_EMP) + empulse(src, 4, 6) + explosion(src, light_impact_range = 3, flash_range = 6) + if(FLUX_NO_EMP) new /obj/effect/particle_effect/sparks(loc) -/// A flux anomaly which doesn't explode or produce a core +/// A flux anomaly which doesn't emp or produce a core /obj/effect/anomaly/flux/minor anomaly_core = null // We need to override the default arguments here to achieve the desired effect -/obj/effect/anomaly/flux/minor/Initialize(mapload, new_lifespan, explosive = FLUX_NO_EXPLOSION) +/obj/effect/anomaly/flux/minor/Initialize(mapload, new_lifespan, emp_zap = FLUX_NO_EMP) return ..() ///Bigger, meaner, immortal flux anomaly diff --git a/code/game/objects/effects/anomalies/anomalies_gravity.dm b/code/game/objects/effects/anomalies/anomalies_gravity.dm index ae22c3294a8..280e0dc1e12 100644 --- a/code/game/objects/effects/anomalies/anomalies_gravity.dm +++ b/code/game/objects/effects/anomalies/anomalies_gravity.dm @@ -1,50 +1,4 @@ -/atom/movable/warp_effect - plane = DISPLACEMENT_PLANE - appearance_flags = PIXEL_SCALE|LONG_GLIDE // no tile bound so you can see it around corners and so - icon = 'icons/effects/light_overlays/light_352.dmi' - icon_state = "light" - pixel_x = -176 - pixel_y = -176 - -/atom/movable/warp_effect/Initialize(mapload) - . = ..() - var/turf/new_turf = get_turf(src) - if(new_turf) - var/new_offset = GET_TURF_PLANE_OFFSET(new_turf) - ADD_TRAIT(GLOB, TRAIT_DISTORTION_IN_USE(new_offset), ref(src)) - -/atom/movable/warp_effect/Destroy(force) - // Just in case I've forgotten how the movement api works - var/offset = GET_TURF_PLANE_OFFSET(loc) - REMOVE_TRAIT(GLOB, TRAIT_DISTORTION_IN_USE(offset), ref(src)) - return ..() - -/atom/movable/warp_effect/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) - . = ..() - var/turf/new_turf = get_turf(src) - var/turf/old_turf = get_turf(old_loc) - if(!new_turf) - var/old_offset = GET_TURF_PLANE_OFFSET(old_turf) - REMOVE_TRAIT(GLOB, TRAIT_DISTORTION_IN_USE(old_offset), ref(src)) - return - else if(get_turf(old_loc)) - return - // If we're in a thing on a turf we COUNT as a distortion source - var/new_offset = GET_TURF_PLANE_OFFSET(new_turf) - ADD_TRAIT(GLOB, TRAIT_DISTORTION_IN_USE(new_offset), ref(src)) - -/atom/movable/warp_effect/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) - . = ..() - if(same_z_layer) - return - if(old_turf) - var/old_offset = GET_TURF_PLANE_OFFSET(old_turf) - REMOVE_TRAIT(GLOB, TRAIT_DISTORTION_IN_USE(old_offset), ref(src)) - if(new_turf) - var/new_offset = GET_TURF_PLANE_OFFSET(new_turf) - ADD_TRAIT(GLOB, TRAIT_DISTORTION_IN_USE(new_offset), ref(src)) - /obj/effect/anomaly/grav name = "gravitational anomaly" icon = 'icons/effects/effects.dmi' @@ -52,8 +6,7 @@ density = FALSE anomaly_core = /obj/item/assembly/signaler/anomaly/grav var/boing = 0 - ///Warp effect holder for displacement filter to "pulse" the anomaly - var/atom/movable/warp_effect/warp + var/object_launch_prob = 20 /obj/effect/anomaly/grav/Initialize(mapload, new_lifespan) . = ..() @@ -63,21 +16,6 @@ AddElement(/datum/element/connect_loc, loc_connections) apply_wibbly_filters(src) - warp = new(src) - vis_contents += warp - -/obj/effect/anomaly/grav/Destroy() - vis_contents -= warp - warp = null - return ..() - -/obj/effect/anomaly/grav/on_changed_z_level(turf/old_turf, turf/new_turf, same_z_layer, notify_contents) - . = ..() - if(same_z_layer) - return - if(warp) - SET_PLANE(warp, PLANE_TO_TRUE(warp.plane), new_turf) - /obj/effect/anomaly/grav/anomalyEffect(seconds_per_tick) ..() boing = 1 @@ -85,7 +23,8 @@ if(!O.anchored) step_towards(O,src) for(var/mob/living/M in range(0, src)) - gravShock(M) + if(!M.mob_negates_gravity()) + gravShock(M) for(var/mob/living/M in orange(4, src)) if(!M.mob_negates_gravity()) step_towards(M,src) @@ -93,13 +32,9 @@ if(O.anchored || HAS_TRAIT(O, TRAIT_UNDERFLOOR)) continue var/mob/living/target = locate() in view(4,src) - if(target && !target.stat) + if(target && !target.stat && prob(object_launch_prob)) O.throw_at(target, 5, 10) - //anomaly quickly contracts then slowly expands its ring - animate(warp, time = seconds_per_tick*3, transform = matrix().Scale(0.5,0.5)) - animate(time = seconds_per_tick*7, transform = matrix()) - /obj/effect/anomaly/grav/proc/on_entered(datum/source, atom/movable/AM) SIGNAL_HANDLER gravShock(AM) @@ -110,11 +45,11 @@ /obj/effect/anomaly/grav/Bumped(atom/movable/AM) gravShock(AM) -/obj/effect/anomaly/grav/proc/gravShock(mob/living/A) - if(boing && isliving(A) && !A.stat) - A.Paralyze(40) - var/atom/target = get_edge_target_turf(A, get_dir(src, get_step_away(A, src))) - A.throw_at(target, 5, 1) +/obj/effect/anomaly/grav/proc/gravShock(mob/living/living_debris) + if(boing && isliving(living_debris) && !living_debris.stat && !living_debris.mob_negates_gravity()) + living_debris.Knockdown(4 SECONDS) + var/atom/target = get_edge_target_turf(living_debris, get_dir(src, get_step_away(living_debris, src))) + living_debris.throw_at(target, 5, 1) boing = 0 /obj/effect/anomaly/grav/detonate() diff --git a/code/game/objects/items/devices/scanners/gas_analyzer.dm b/code/game/objects/items/devices/scanners/gas_analyzer.dm index 161d9b9a88e..b222be2decb 100644 --- a/code/game/objects/items/devices/scanners/gas_analyzer.dm +++ b/code/game/objects/items/devices/scanners/gas_analyzer.dm @@ -148,6 +148,10 @@ ui_interact(user) /obj/item/analyzer/ranged_interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) + if(istype(interacting_with, /obj/effect/anomaly) && can_see(user, interacting_with, ranged_scan_distance)) + var/obj/effect/anomaly/ranged_anomaly = interacting_with + ranged_anomaly.analyzer_act(user, src) + return ITEM_INTERACT_SUCCESS return interact_with_atom(interacting_with, user, modifiers) /obj/item/analyzer/interact_with_atom(atom/interacting_with, mob/living/user, list/modifiers) diff --git a/code/modules/power/supermatter/supermatter_extra_effects.dm b/code/modules/power/supermatter/supermatter_extra_effects.dm index fe3f69ef60b..0724667300f 100644 --- a/code/modules/power/supermatter/supermatter_extra_effects.dm +++ b/code/modules/power/supermatter/supermatter_extra_effects.dm @@ -165,7 +165,7 @@ return switch(type) if(FLUX_ANOMALY) - var/explosive = has_changed_lifespan ? FLUX_NO_EXPLOSION : FLUX_LOW_EXPLOSIVE + var/explosive = has_changed_lifespan ? FLUX_NO_EMP : FLUX_LIGHT_EMP new /obj/effect/anomaly/flux(local_turf, has_changed_lifespan ? rand(25 SECONDS, 35 SECONDS) : null, FALSE, explosive) if(GRAVITATIONAL_ANOMALY) new /obj/effect/anomaly/grav(local_turf, has_changed_lifespan ? rand(20 SECONDS, 30 SECONDS) : null, FALSE)