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