From 74900c7e85cbe4195364ed062139ee6fe63fb3e5 Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Tue, 14 Feb 2023 17:49:32 -0600 Subject: [PATCH] FIxes Time Stop being a 3x3 instead of a 5x5 (no seriously) (#73339) ## About The Pull Request Keen eyes will notice time stop is intended to have a radius of 2 https://github.com/tgstation/tgstation/blob/3c0013dfa5198db867426ea27df14534cf95949f/code/modules/spells/spell_types/self/stop_time.dm#L14-L17 This implies it's supposed to be a 5x5 - radius of 2 Back when it was originally coded, it was a 5x5 https://github.com/tgstation/tgstation/commit/f2abe13f513afb9f2a18e4e3eb4756494d84e4cf (scroll down a bit, and you will see `orange(2)`. This is a 5x5.) So where did it become a 3x3? I can't find a single PR nerfing it, and the radius is still 2 as it always has been The answer: Here, in 2017 it was refactored to use fields #30858 Fields track their inner fields and edge fields separately, but it used the same radius as before, so it quietly shrunk by 1 tile as the outer edge was no longer counted as frozen, and I guess no one noticed? or cared? I don't know?? So I updated advanced fields to have a "mode" that tracks edge fields as field turfs. While I was here, I fixed some other issues with timestop. A runtime when movelooping mobs were time stopped, sign languagers (emote mute). And while I was "while I was here", Gravity aura had a similar issue, causing the grav gen's aura to never work. That was fixed as well ## Why It's Good For The Game This caused an hour long search over a 5 year old bug ## Changelog :cl: Melbert fix: Fixed a FIVE YEAR OLD issue causing Time Stop to be a 3x3 instead of a 5x5. Really. fix: The gravity generator correctly gives "forced gravity" to all adjacent mobs fix: Fixed some runtimes with Time Stop, and other miscellaneous issues /:cl: --- code/datums/proximity_monitor/field.dm | 34 ++++++++++++++++--- .../proximity_monitor/fields/gravity.dm | 23 +++++++------ .../proximity_monitor/fields/timestop.dm | 12 ++++--- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/code/datums/proximity_monitor/field.dm b/code/datums/proximity_monitor/field.dm index 43fdb8bb20b..12c033cc426 100644 --- a/code/datums/proximity_monitor/field.dm +++ b/code/datums/proximity_monitor/field.dm @@ -5,9 +5,19 @@ * Movable and easily code-modified fields! Allows for custom AOE effects that affect movement * and anything inside of them, and can do custom turf effects! * Supports automatic recalculation/reset on movement. + * + * "What do I gain from using advanced over standard prox monitors?" + * - You can set different effects on edge vs field entrance + * - You can set effects when the proximity monitor starts and stops tracking a turf */ /datum/proximity_monitor/advanced + /// If TRUE, edge turfs will be included as "in the field" for effects + /// Can be used in certain situations where you may have effects that trigger only at the edge, + /// while also wanting the field effect to trigger at edge turfs as well + var/edge_is_a_field = FALSE + /// All turfs on the inside of the proximity monitor - range - 1 turfs var/list/turf/field_turfs = list() + /// All turfs on the very last tile of the proximity monitor's radius var/list/turf/edge_turfs = list() /datum/proximity_monitor/advanced/Destroy() @@ -34,8 +44,10 @@ cleanup_edge_turf(old_turf) for(var/turf/new_turf as anything in new_field_turfs) + field_turfs |= new_turf setup_field_turf(new_turf) for(var/turf/new_turf as anything in new_edge_turfs) + edge_turfs |= new_turf setup_edge_turf(new_turf) /datum/proximity_monitor/advanced/on_entered(turf/source, atom/movable/entered) @@ -64,16 +76,23 @@ else field_turf_uncrossed(gone, source) +/// Called when a turf in the field of the monitor is linked /datum/proximity_monitor/advanced/proc/setup_field_turf(turf/target) - field_turfs |= target + return +/// Called when a turf in the field of the monitor is unlinked /datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/target) field_turfs -= target +/// Called when a turf in the edge of the monitor is linked /datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/target) - edge_turfs |= target + if(edge_is_a_field) // If the edge is considered a field, set it up like one + setup_field_turf(target) +/// Called when a turf in the edge of the monitor is unlinked /datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/target) + if(edge_is_a_field) // If the edge is considered a field, clean it up like one + cleanup_field_turf(target) edge_turfs -= target /datum/proximity_monitor/advanced/proc/update_new_turfs() @@ -112,11 +131,12 @@ return /datum/proximity_monitor/advanced/proc/field_edge_crossed(atom/movable/movable, turf/location) - return + if(edge_is_a_field) // If the edge is considered a field, pass crossed to that + field_turf_crossed(movable, location) /datum/proximity_monitor/advanced/proc/field_edge_uncrossed(atom/movable/movable, turf/location) - return - + if(edge_is_a_field) // If the edge is considered a field, pass uncrossed to that + field_turf_uncrossed(movable, location) //DEBUG FIELD ITEM /obj/item/multitool/field_debug @@ -143,6 +163,10 @@ else if(!operating) QDEL_NULL(current) +/obj/item/multitool/field_debug/attack_self_secondary(mob/user, modifiers) + current.edge_is_a_field = !current.edge_is_a_field + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + //DEBUG FIELDS /datum/proximity_monitor/advanced/debug current_range = 5 diff --git a/code/datums/proximity_monitor/fields/gravity.dm b/code/datums/proximity_monitor/fields/gravity.dm index bdabf97ac1e..181e74157cd 100644 --- a/code/datums/proximity_monitor/fields/gravity.dm +++ b/code/datums/proximity_monitor/fields/gravity.dm @@ -1,4 +1,5 @@ /datum/proximity_monitor/advanced/gravity + edge_is_a_field = TRUE var/gravity_value = 0 var/list/modified_turfs = list() @@ -7,15 +8,17 @@ gravity_value = gravity recalculate_field() -/datum/proximity_monitor/advanced/gravity/setup_field_turf(turf/T) +/datum/proximity_monitor/advanced/gravity/setup_field_turf(turf/target) . = ..() - - if (!isnull(modified_turfs[T])) - T.AddElement(/datum/element/forced_gravity, gravity_value) - -/datum/proximity_monitor/advanced/gravity/cleanup_field_turf(turf/T) - . = ..() - if(isnull(modified_turfs[T])) + if (isnull(modified_turfs[target])) return - T.RemoveElement(/datum/element/forced_gravity, modified_turfs[T]) - modified_turfs -= T + + target.AddElement(/datum/element/forced_gravity, gravity_value) + modified_turfs[target] = gravity_value + +/datum/proximity_monitor/advanced/gravity/cleanup_field_turf(turf/target) + . = ..() + if(isnull(modified_turfs[target])) + return + target.RemoveElement(/datum/element/forced_gravity, modified_turfs[target]) + modified_turfs -= target diff --git a/code/datums/proximity_monitor/fields/timestop.dm b/code/datums/proximity_monitor/fields/timestop.dm index ef4b744db49..a7a1fd3db26 100644 --- a/code/datums/proximity_monitor/fields/timestop.dm +++ b/code/datums/proximity_monitor/fields/timestop.dm @@ -58,6 +58,7 @@ channelled = TRUE /datum/proximity_monitor/advanced/timestop + edge_is_a_field = TRUE var/list/immune = list() var/list/frozen_things = list() var/list/frozen_mobs = list() //cached separately for processing @@ -187,12 +188,11 @@ var/mob/living/m = i m.Stun(20, ignore_canstun = TRUE) -/datum/proximity_monitor/advanced/timestop/setup_field_turf(turf/T) +/datum/proximity_monitor/advanced/timestop/setup_field_turf(turf/target) . = ..() - for(var/i in T.contents) + for(var/i in target.contents) freeze_atom(i) - freeze_turf(T) - + freeze_turf(target) /datum/proximity_monitor/advanced/timestop/proc/freeze_projectile(obj/projectile/P) P.paused = TRUE @@ -204,7 +204,8 @@ frozen_mobs += L L.Stun(20, ignore_canstun = TRUE) ADD_TRAIT(L, TRAIT_MUTE, TIMESTOP_TRAIT) - SSmove_manager.stop_looping(src) //stops them mid pathing even if they're stunimmune //This is really dumb + ADD_TRAIT(L, TRAIT_EMOTEMUTE, TIMESTOP_TRAIT) + SSmove_manager.stop_looping(L) //stops them mid pathing even if they're stunimmune //This is really dumb if(isanimal(L)) var/mob/living/simple_animal/S = L S.toggle_ai(AI_OFF) @@ -215,6 +216,7 @@ /datum/proximity_monitor/advanced/timestop/proc/unfreeze_mob(mob/living/L) L.AdjustStun(-20, ignore_canstun = TRUE) REMOVE_TRAIT(L, TRAIT_MUTE, TIMESTOP_TRAIT) + REMOVE_TRAIT(L, TRAIT_EMOTEMUTE, TIMESTOP_TRAIT) frozen_mobs -= L if(isanimal(L)) var/mob/living/simple_animal/S = L