From 12bf03aa0805d2888dc2f54090af25da8b620952 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Wed, 22 Dec 2021 08:49:08 +0100 Subject: [PATCH] proximity monitors cleanup (plus connect_range and connect_containers components) (#62755) I'm refactoring proximity monitors and fields, removing lots of bloat from both that's hardly even used. Proximity monitors no longer generate effect objects to track the surrounding area, should be less cpu expensive and easier to maintain (or phase out), read and use. This PR also adds a couple components which may be needed for future stuff (for starters, the mirror reflection PR #62638 could use the connect_range comp) Improving old old, ugly old code and adding some useful backend components. Tested and working. --- code/__DEFINES/subsystems.dm | 1 - code/__HELPERS/atoms.dm | 11 + code/__HELPERS/turfs.dm | 12 - .../subsystem/processing/fields.dm | 6 - code/datums/components/connect_containers.dm | 68 ++++ code/datums/components/connect_loc_behalf.dm | 14 +- code/datums/components/connect_range.dm | 106 ++++++ code/datums/elements/connect_loc.dm | 3 +- code/datums/proximity_monitor/field.dm | 169 +++++++++ .../proximity_monitor}/fields/gravity.dm | 8 +- .../fields/peaceborg_dampener.dm | 80 ++--- .../proximity_monitor}/fields/timestop.dm | 21 +- .../proximity_monitor/proximity_monitor.dm | 78 +++++ code/datums/wires/explosive.dm | 7 +- code/game/atoms.dm | 2 - code/game/atoms_movable.dm | 1 - code/game/machinery/camera/camera.dm | 4 +- code/game/machinery/camera/motion.dm | 2 +- code/game/machinery/flasher.dm | 6 +- code/game/machinery/hologram.dm | 2 + code/game/objects/effects/anomalies.dm | 4 +- code/game/objects/effects/proximity.dm | 129 ------- code/game/objects/items/robot/robot_items.dm | 12 +- code/game/objects/structures/aliens.dm | 6 +- code/game/turfs/turf.dm | 5 +- code/modules/admin/verbs/secrets.dm | 2 +- code/modules/assembly/proximity.dm | 12 +- code/modules/fields/fields.dm | 324 ------------------ code/modules/fields/turf_objects.dm | 70 ---- code/modules/mining/machine_processing.dm | 2 + code/modules/mining/machine_stacking.dm | 2 + code/modules/power/gravitygenerator.dm | 2 +- code/modules/shuttle/on_move.dm | 6 - code/modules/unit_tests/create_and_destroy.dm | 2 - tgstation.dme | 14 +- 35 files changed, 534 insertions(+), 659 deletions(-) delete mode 100644 code/controllers/subsystem/processing/fields.dm create mode 100644 code/datums/components/connect_containers.dm create mode 100644 code/datums/components/connect_range.dm create mode 100644 code/datums/proximity_monitor/field.dm rename code/{modules => datums/proximity_monitor}/fields/gravity.dm (74%) rename code/{modules => datums/proximity_monitor}/fields/peaceborg_dampener.dm (67%) rename code/{modules => datums/proximity_monitor}/fields/timestop.dm (92%) create mode 100644 code/datums/proximity_monitor/proximity_monitor.dm delete mode 100644 code/game/objects/effects/proximity.dm delete mode 100644 code/modules/fields/fields.dm delete mode 100644 code/modules/fields/turf_objects.dm diff --git a/code/__DEFINES/subsystems.dm b/code/__DEFINES/subsystems.dm index 589fdd2c3e1..8afb146fdca 100644 --- a/code/__DEFINES/subsystems.dm +++ b/code/__DEFINES/subsystems.dm @@ -181,7 +181,6 @@ #define FIRE_PRIORITY_THROWING 25 #define FIRE_PRIORITY_REAGENTS 26 #define FIRE_PRIORITY_SPACEDRIFT 30 -#define FIRE_PRIORITY_FIELDS 30 #define FIRE_PRIOTITY_SMOOTHING 35 #define FIRE_PRIORITY_NETWORKS 40 #define FIRE_PRIORITY_OBJ 40 diff --git a/code/__HELPERS/atoms.dm b/code/__HELPERS/atoms.dm index 0e6b916830f..5762d40f640 100644 --- a/code/__HELPERS/atoms.dm +++ b/code/__HELPERS/atoms.dm @@ -33,6 +33,17 @@ processing += checked_atom.contents . += checked_atom +///Returns a list of all locations (except the area) the movable is within. +/proc/get_nested_locs(atom/movable/atom_on_location, include_turf = FALSE) + . = list() + var/atom/location = atom_on_location.loc + var/turf/our_turf = get_turf(atom_on_location) + while(location && location != our_turf) + . += location + location = location.loc + if(our_turf && include_turf) //At this point, only the turf is left, provided it exists. + . += our_turf + ///Step-towards method of determining whether one atom can see another. Similar to viewers() ///note: this is a line of sight algorithm, view() does not do any sort of raycasting and cannot be emulated by it accurately /proc/can_see(atom/source, atom/target, length=5) // I couldnt be arsed to do actual raycasting :I This is horribly inaccurate. diff --git a/code/__HELPERS/turfs.dm b/code/__HELPERS/turfs.dm index bf7ded46084..4c8b62b69dd 100644 --- a/code/__HELPERS/turfs.dm +++ b/code/__HELPERS/turfs.dm @@ -110,18 +110,6 @@ Turf and target are separate in case you want to teleport some distance from a t break return turf_to_check -///Returns a list of all locations (except the area) the movable is within. -/proc/get_nested_locs(atom/movable/atom_on_location, include_turf = FALSE) - . = list() - var/atom/location = atom_on_location.loc - var/turf/turf = get_turf(atom_on_location) - while(location && location != turf) - . += location - location = location.loc - if(location && include_turf) //At this point, only the turf is left, provided it exists. - . += location - - ///Returns the turf located at the map edge in the specified direction relative to target_atom used for mass driver /proc/get_edge_target_turf(atom/target_atom, direction) var/turf/target = locate(target_atom.x, target_atom.y, target_atom.z) diff --git a/code/controllers/subsystem/processing/fields.dm b/code/controllers/subsystem/processing/fields.dm deleted file mode 100644 index a4c58b883a8..00000000000 --- a/code/controllers/subsystem/processing/fields.dm +++ /dev/null @@ -1,6 +0,0 @@ -PROCESSING_SUBSYSTEM_DEF(fields) - name = "Fields" - wait = 2 - priority = FIRE_PRIORITY_FIELDS - flags = SS_KEEP_TIMING | SS_NO_INIT - runlevels = RUNLEVEL_GAME | RUNLEVEL_POSTGAME diff --git a/code/datums/components/connect_containers.dm b/code/datums/components/connect_containers.dm new file mode 100644 index 00000000000..c386a096410 --- /dev/null +++ b/code/datums/components/connect_containers.dm @@ -0,0 +1,68 @@ +/// This component behaves similar to connect_loc_behalf, but it's nested and hooks a signal onto all MOVABLES containing this atom. +/datum/component/connect_containers + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + + /// An assoc list of signal -> procpath to register to the loc this object is on. + var/list/connections + /** + * The atom the component is tracking. The component will delete itself if the tracked is deleted. + * Signals will also be updated whenever it moves. + */ + var/atom/movable/tracked + +/datum/component/connect_containers/Initialize(atom/movable/tracked, list/connections) + . = ..() + if (!ismovable(tracked)) + return COMPONENT_INCOMPATIBLE + + src.connections = connections + set_tracked(tracked) + +/datum/component/connect_containers/Destroy() + set_tracked(null) + return ..() + +/datum/component/connect_containers/InheritComponent(datum/component/component, original, atom/movable/tracked, list/connections) + // Not equivalent. Checks if they are not the same list via shallow comparison. + if(!compare_list(src.connections, connections)) + stack_trace("connect_containers component attached to [parent] tried to inherit another connect_containers component with different connections") + return + if(src.tracked != tracked) + set_tracked(tracked) + +/datum/component/connect_containers/proc/set_tracked(atom/movable/new_tracked) + if(tracked) + UnregisterSignal(tracked, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) + unregister_signals(tracked.loc) + tracked = new_tracked + if(!tracked) + return + RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, .proc/on_moved) + RegisterSignal(tracked, COMSIG_PARENT_QDELETING, .proc/handle_tracked_qdel) + update_signals(tracked) + +/datum/component/connect_containers/proc/handle_tracked_qdel() + SIGNAL_HANDLER + qdel(src) + +/datum/component/connect_containers/proc/update_signals(atom/movable/listener) + if(!ismovable(listener.loc)) + return + + for(var/atom/movable/container as anything in get_nested_locs(listener)) + RegisterSignal(container, COMSIG_MOVABLE_MOVED, .proc/on_moved) + for(var/signal in connections) + parent.RegisterSignal(container, signal, connections[signal]) + +/datum/component/connect_containers/proc/unregister_signals(atom/movable/location) + if(!ismovable(location)) + return + + for(var/atom/movable/target as anything in (get_nested_locs(location) + location)) + UnregisterSignal(target, COMSIG_MOVABLE_MOVED) + parent.UnregisterSignal(target, connections) + +/datum/component/connect_containers/proc/on_moved(atom/movable/listener, atom/old_loc) + SIGNAL_HANDLER + unregister_signals(old_loc) + update_signals(listener) diff --git a/code/datums/components/connect_loc_behalf.dm b/code/datums/components/connect_loc_behalf.dm index f6552df459e..b758b6ad5f3 100644 --- a/code/datums/components/connect_loc_behalf.dm +++ b/code/datums/components/connect_loc_behalf.dm @@ -19,17 +19,6 @@ src.connections = connections src.tracked = tracked -/datum/component/connect_loc_behalf/CheckDupeComponent(datum/component/component, atom/movable/tracked, list/connections) - if(src.tracked != tracked) - return FALSE - - // Not equivalent. Checks if they are not the same list via shallow comparison. - if(!compare_list(src.connections, connections)) - return FALSE - - return TRUE - - /datum/component/connect_loc_behalf/RegisterWithParent() RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, .proc/on_moved) RegisterSignal(tracked, COMSIG_PARENT_QDELETING, .proc/handle_tracked_qdel) @@ -70,8 +59,7 @@ if(isnull(tracked_loc)) return - for (var/signal in connections) - parent.UnregisterSignal(tracked_loc, signal) + parent.UnregisterSignal(tracked_loc, connections) tracked_loc = null diff --git a/code/datums/components/connect_range.dm b/code/datums/components/connect_range.dm new file mode 100644 index 00000000000..3e14b6a6428 --- /dev/null +++ b/code/datums/components/connect_range.dm @@ -0,0 +1,106 @@ +/** + * This component behaves similar to connect_loc_behalf but for all turfs in range, hooking into a signal on each of them. + * Just like connect_loc_behalf, It can react to that signal on behalf of a seperate listener. + * Good for components, though it carries some overhead. Can't be an element as that may lead to bugs. + */ +/datum/component/connect_range + dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS + + /// An assoc list of signal -> procpath to register to the loc this object is on. + var/list/connections + /** + * The atom the component is tracking. The component will delete itself if the tracked is deleted. + * Signals will also be updated whenever it moves (if it's a movable). + */ + var/atom/tracked + + /// The component will hook into signals only on turfs not farther from tracked than this. + var/range + /// Whether the component works when the movable isn't directly located on a turf. + var/works_in_containers + +/datum/component/connect_range/Initialize(atom/tracked, list/connections, range, works_in_containers = TRUE) + if(!isatom(tracked) || isarea(tracked) || range < 0) + return COMPONENT_INCOMPATIBLE + src.connections = connections + set_tracked(tracked) + src.works_in_containers = works_in_containers + +/datum/component/connect_range/Destroy() + set_tracked(null) + return ..() + +/datum/component/connect_range/InheritComponent(datum/component/component, original, atom/tracked, list/connections, range, works_in_containers) + // Not equivalent. Checks if they are not the same list via shallow comparison. + if(!compare_list(src.connections, connections)) + stack_trace("connect_range component attached to [parent] tried to inherit another connect_range component with different connections") + return + if(src.tracked != tracked) + set_tracked(tracked) + if(src.range == range && src.works_in_containers == works_in_containers) + return + //Unregister the signals with the old settings. + unregister_signals(isturf(tracked) ? tracked : tracked.loc) + src.range = range + src.works_in_containers = works_in_containers + //Re-register the signals with the new settings. + update_signals(src.tracked) + +/datum/component/connect_range/proc/set_tracked(atom/new_tracked) + if(tracked) //Unregister the signals from the old tracked and its surroundings + unregister_signals(isturf(tracked) ? tracked : tracked.loc) + UnregisterSignal(tracked, list( + COMSIG_MOVABLE_MOVED, + COMSIG_PARENT_QDELETING, + )) + tracked = new_tracked + if(!tracked) + return + //Register signals on the new tracked atom and its surroundings. + RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, .proc/on_moved) + RegisterSignal(tracked, COMSIG_PARENT_QDELETING, .proc/handle_tracked_qdel) + update_signals(tracked) + +/datum/component/connect_range/proc/handle_tracked_qdel() + SIGNAL_HANDLER + qdel(src) + +/datum/component/connect_range/proc/update_signals(atom/target, atom/old_loc, forced = FALSE) + var/turf/current_turf = get_turf(target) + var/on_same_turf = current_turf == get_turf(old_loc) //Only register/unregister turf signals if it's moved to a new turf. + unregister_signals(old_loc, on_same_turf) + + if(isnull(current_turf)) + return + + if(ismovable(target.loc)) + if(!works_in_containers) + return + //Keep track of possible movement of all movables the target is in. + for(var/atom/movable/container as anything in get_nested_locs(target)) + RegisterSignal(container, COMSIG_MOVABLE_MOVED, .proc/on_moved) + + if(on_same_turf && !forced) + return + for(var/turf/target_turf in RANGE_TURFS(range, current_turf)) + for(var/signal in connections) + parent.RegisterSignal(target_turf, signal, connections[signal]) + +/datum/component/connect_range/proc/unregister_signals(atom/location, on_same_turf = FALSE) + //The location is null or is a container and the component shouldn't have register signals on it + if(isnull(location) || (!works_in_containers && !isturf(location))) + return + + if(ismovable(location)) + for(var/atom/movable/target as anything in (get_nested_locs(location) + location)) + UnregisterSignal(target, COMSIG_MOVABLE_MOVED) + + if(on_same_turf) + return + var/turf/previous_turf = get_turf(location) + for(var/turf/target_turf in RANGE_TURFS(range, previous_turf)) + parent.UnregisterSignal(target_turf, connections) + +/datum/component/connect_range/proc/on_moved(atom/movable/movable, atom/old_loc) + SIGNAL_HANDLER + update_signals(movable, old_loc) diff --git a/code/datums/elements/connect_loc.dm b/code/datums/elements/connect_loc.dm index 1687ce35f56..fee9072f751 100644 --- a/code/datums/elements/connect_loc.dm +++ b/code/datums/elements/connect_loc.dm @@ -35,8 +35,7 @@ if(isnull(old_loc)) return - for (var/signal in connections) - listener.UnregisterSignal(old_loc, signal) + listener.UnregisterSignal(old_loc, connections) /datum/element/connect_loc/proc/on_moved(atom/movable/listener, atom/old_loc) SIGNAL_HANDLER diff --git a/code/datums/proximity_monitor/field.dm b/code/datums/proximity_monitor/field.dm new file mode 100644 index 00000000000..43fdb8bb20b --- /dev/null +++ b/code/datums/proximity_monitor/field.dm @@ -0,0 +1,169 @@ +#define FIELD_TURFS_KEY "field_turfs" +#define EDGE_TURFS_KEY "edge_turfs" + +/** + * 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. + */ +/datum/proximity_monitor/advanced + var/list/turf/field_turfs = list() + var/list/turf/edge_turfs = list() + +/datum/proximity_monitor/advanced/Destroy() + cleanup_field() + return ..() + +/datum/proximity_monitor/advanced/proc/cleanup_field() + for(var/turf/turf as anything in edge_turfs) + cleanup_edge_turf(turf) + for(var/turf/turf as anything in field_turfs) + cleanup_field_turf(turf) + +//Call every time the field moves (done automatically if you use update_center) or a setup specification is changed. +/datum/proximity_monitor/advanced/proc/recalculate_field() + var/list/new_turfs = update_new_turfs() + + var/list/new_field_turfs = new_turfs[FIELD_TURFS_KEY] + var/list/new_edge_turfs = new_turfs[EDGE_TURFS_KEY] + + for(var/turf/old_turf as anything in field_turfs) + if(!(old_turf in new_field_turfs)) + cleanup_field_turf(old_turf) + for(var/turf/old_turf as anything in edge_turfs) + cleanup_edge_turf(old_turf) + + for(var/turf/new_turf as anything in new_field_turfs) + setup_field_turf(new_turf) + for(var/turf/new_turf as anything in new_edge_turfs) + setup_edge_turf(new_turf) + +/datum/proximity_monitor/advanced/on_entered(turf/source, atom/movable/entered) + . = ..() + if(get_dist(source, host) == current_range) + field_edge_crossed(entered, source) + else + field_turf_crossed(entered, source) + +/datum/proximity_monitor/advanced/on_moved(atom/movable/movable, atom/old_loc) + . = ..() + if(ignore_if_not_on_turf) + //Early return if it's not the host that has moved. + if(movable != host) + return + //Cleanup the field if the host was on a turf but isn't anymore. + if(!isturf(host.loc)) + if(isturf(old_loc)) + cleanup_field() + return + recalculate_field() + +/datum/proximity_monitor/advanced/on_uncrossed(turf/source, atom/movable/gone, direction) + if(get_dist(source, host) == current_range) + field_edge_uncrossed(gone, source) + else + field_turf_uncrossed(gone, source) + +/datum/proximity_monitor/advanced/proc/setup_field_turf(turf/target) + field_turfs |= target + +/datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/target) + field_turfs -= target + +/datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/target) + edge_turfs |= target + +/datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/target) + edge_turfs -= target + +/datum/proximity_monitor/advanced/proc/update_new_turfs() + . = list(FIELD_TURFS_KEY = list(), EDGE_TURFS_KEY = list()) + if(ignore_if_not_on_turf && !isturf(host.loc)) + return + var/turf/center = get_turf(host) + for(var/turf/target in RANGE_TURFS(current_range, center)) + if(get_dist(center, target) == current_range) + .[EDGE_TURFS_KEY] += target + else + .[FIELD_TURFS_KEY] += target + +//Gets edge direction/corner, only works with square radius/WDH fields! +/datum/proximity_monitor/advanced/proc/get_edgeturf_direction(turf/T, turf/center_override = null) + var/turf/checking_from = get_turf(host) + if(istype(center_override)) + checking_from = center_override + if(!(T in edge_turfs)) + return + if(((T.x == (checking_from.x + current_range)) || (T.x == (checking_from.x - current_range))) && ((T.y == (checking_from.y + current_range)) || (T.y == (checking_from.y - current_range)))) + return get_dir(checking_from, T) + if(T.x == (checking_from.x + current_range)) + return EAST + if(T.x == (checking_from.x - current_range)) + return WEST + if(T.y == (checking_from.y - current_range)) + return SOUTH + if(T.y == (checking_from.y + current_range)) + return NORTH + +/datum/proximity_monitor/advanced/proc/field_turf_crossed(atom/movable/movable, turf/location) + return + +/datum/proximity_monitor/advanced/proc/field_turf_uncrossed(atom/movable/movable, turf/location) + return + +/datum/proximity_monitor/advanced/proc/field_edge_crossed(atom/movable/movable, turf/location) + return + +/datum/proximity_monitor/advanced/proc/field_edge_uncrossed(atom/movable/movable, turf/location) + return + + +//DEBUG FIELD ITEM +/obj/item/multitool/field_debug + name = "strange multitool" + desc = "Seems to project a colored field!" + var/operating = FALSE + var/datum/proximity_monitor/advanced/debug/current = null + +/obj/item/multitool/field_debug/Destroy() + QDEL_NULL(current) + return ..() + +/obj/item/multitool/field_debug/proc/setup_debug_field() + current = new(src, 5, FALSE) + current.set_fieldturf_color = "#aaffff" + current.set_edgeturf_color = "#ffaaff" + current.recalculate_field() + +/obj/item/multitool/field_debug/attack_self(mob/user) + operating = !operating + to_chat(user, span_notice("You turn [src] [operating? "on":"off"].")) + if(!istype(current) && operating) + setup_debug_field() + else if(!operating) + QDEL_NULL(current) + +//DEBUG FIELDS +/datum/proximity_monitor/advanced/debug + current_range = 5 + var/set_fieldturf_color = "#aaffff" + var/set_edgeturf_color = "#ffaaff" + +/datum/proximity_monitor/advanced/debug/setup_edge_turf(turf/target) + . = ..() + target.color = set_edgeturf_color + +/datum/proximity_monitor/advanced/debug/cleanup_edge_turf(turf/target) + . = ..() + target.color = initial(target.color) + +/datum/proximity_monitor/advanced/debug/setup_field_turf(turf/target) + . = ..() + target.color = set_fieldturf_color + +/datum/proximity_monitor/advanced/debug/cleanup_field_turf(turf/target) + . = ..() + target.color = initial(target.color) + +#undef FIELD_TURFS_KEY +#undef EDGE_TURFS_KEY diff --git a/code/modules/fields/gravity.dm b/code/datums/proximity_monitor/fields/gravity.dm similarity index 74% rename from code/modules/fields/gravity.dm rename to code/datums/proximity_monitor/fields/gravity.dm index 0914993174a..bdabf97ac1e 100644 --- a/code/modules/fields/gravity.dm +++ b/code/datums/proximity_monitor/fields/gravity.dm @@ -1,9 +1,11 @@ /datum/proximity_monitor/advanced/gravity - name = "modified gravity zone" - setup_field_turfs = TRUE var/gravity_value = 0 var/list/modified_turfs = list() - field_shape = FIELD_SHAPE_RADIUS_SQUARE + +/datum/proximity_monitor/advanced/gravity/New(atom/_host, range, _ignore_if_not_on_turf = TRUE, gravity) + . = ..() + gravity_value = gravity + recalculate_field() /datum/proximity_monitor/advanced/gravity/setup_field_turf(turf/T) . = ..() diff --git a/code/modules/fields/peaceborg_dampener.dm b/code/datums/proximity_monitor/fields/peaceborg_dampener.dm similarity index 67% rename from code/modules/fields/peaceborg_dampener.dm rename to code/datums/proximity_monitor/fields/peaceborg_dampener.dm index 2f5565327da..16b637afada 100644 --- a/code/modules/fields/peaceborg_dampener.dm +++ b/code/datums/proximity_monitor/fields/peaceborg_dampener.dm @@ -2,11 +2,6 @@ //Projectile dampening field that slows projectiles and lowers their damage for an energy cost deducted every 1/5 second. //Only use square radius for this! /datum/proximity_monitor/advanced/peaceborg_dampener - name = "\improper Hyperkinetic Dampener Field" - setup_edge_turfs = TRUE - setup_field_turfs = TRUE - requires_processing = TRUE - field_shape = FIELD_SHAPE_RADIUS_SQUARE var/static/image/edgeturf_south = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_south") var/static/image/edgeturf_north = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_north") var/static/image/edgeturf_west = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_west") @@ -17,21 +12,26 @@ var/static/image/southeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_southeast") var/static/image/generic_edge = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_generic") var/obj/item/borg/projectile_dampen/projector = null - var/list/obj/projectile/tracked - var/list/obj/projectile/staging - use_host_turf = TRUE + var/list/obj/projectile/tracked = list() + var/list/obj/projectile/staging = list() + // lazylist that keeps track of the overlays added to the edge of the field + var/list/edgeturf_effects -/datum/proximity_monitor/advanced/peaceborg_dampener/New(atom/_host, range, _ignore_if_not_on_turf = TRUE) - tracked = list() - staging = list() - return ..() +/datum/proximity_monitor/advanced/peaceborg_dampener/New(atom/_host, range, _ignore_if_not_on_turf = TRUE, obj/item/borg/projectile_dampen/projector) + ..() + src.projector = projector + recalculate_field() + START_PROCESSING(SSfastprocess, src) /datum/proximity_monitor/advanced/peaceborg_dampener/Destroy() + projector = null + STOP_PROCESSING(SSfastprocess, src) return ..() /datum/proximity_monitor/advanced/peaceborg_dampener/process() if(!istype(projector)) qdel(src) + return var/list/ranged = list() for(var/obj/projectile/P in range(current_range, get_turf(host))) ranged += P @@ -41,23 +41,28 @@ for(var/mob/living/silicon/robot/R in range(current_range, get_turf(host))) if(R.has_buckled_mobs()) for(var/mob/living/L in R.buckled_mobs) - L.visible_message(span_warning("[L] is knocked off of [R] by the charge in [R]'s chassis induced by [name]!")) //I know it's bad. + L.visible_message(span_warning("[L] is knocked off of [R] by the charge in [R]'s chassis induced by the hyperkinetic dampener field!")) //I know it's bad. L.Paralyze(10) R.unbuckle_mob(L) do_sparks(5, 0, L) ..() -/datum/proximity_monitor/advanced/peaceborg_dampener/setup_edge_turf(turf/T) - ..() - var/image/I = get_edgeturf_overlay(get_edgeturf_direction(T)) - var/obj/effect/abstract/proximity_checker/advanced/F = edge_turfs[T] - F.appearance = I.appearance - F.invisibility = 0 - F.mouse_opacity = MOUSE_OPACITY_TRANSPARENT - F.layer = 5 +/datum/proximity_monitor/advanced/peaceborg_dampener/setup_edge_turf(turf/target) + . = ..() + var/image/overlay = get_edgeturf_overlay(get_edgeturf_direction(target)) + var/obj/effect/abstract/effect = new(target) // Makes the field visible to players. + effect.icon = overlay.icon + effect.icon_state = overlay.icon_state + effect.mouse_opacity = MOUSE_OPACITY_TRANSPARENT + effect.layer = ABOVE_ALL_MOB_LAYER + LAZYSET(edgeturf_effects, target, effect) -/datum/proximity_monitor/advanced/peaceborg_dampener/cleanup_edge_turf(turf/T) - ..() +/datum/proximity_monitor/advanced/peaceborg_dampener/cleanup_edge_turf(turf/target) + . = ..() + var/obj/effect/abstract/effect = LAZYACCESS(edgeturf_effects, target) + LAZYREMOVE(edgeturf_effects, target) + if(effect) + qdel(effect) /datum/proximity_monitor/advanced/peaceborg_dampener/proc/get_edgeturf_overlay(direction) switch(direction) @@ -91,24 +96,13 @@ projector.restore_projectile(P) tracked -= P -/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F) - if(!is_turf_in_field(get_turf(AM), src)) - if(istype(AM, /obj/projectile)) - if(AM in tracked) - release_projectile(AM) - else - capture_projectile(AM, FALSE) - return ..() +/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_uncrossed(atom/movable/movable, turf/location) + if(istype(movable, /obj/projectile) && get_dist(movable, host) > current_range) + if(movable in tracked) + release_projectile(movable) + else + capture_projectile(movable, FALSE) -/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F) - if(istype(AM, /obj/projectile) && !(AM in tracked) && staging[AM] && !is_turf_in_field(staging[AM], src)) - capture_projectile(AM) - staging -= AM - return ..() - -/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F, border_dir) - if(istype(AM, /obj/projectile)) - staging[AM] = get_turf(AM) - . = ..() - if(!.) - staging -= AM //This one ain't goin' through. +/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_crossed(atom/movable/movable, turf/location) + if(istype(movable, /obj/projectile) && !(movable in tracked)) + capture_projectile(movable) diff --git a/code/modules/fields/timestop.dm b/code/datums/proximity_monitor/fields/timestop.dm similarity index 92% rename from code/modules/fields/timestop.dm rename to code/datums/proximity_monitor/fields/timestop.dm index ed0f2ccf1af..0610e6d4155 100644 --- a/code/modules/fields/timestop.dm +++ b/code/datums/proximity_monitor/fields/timestop.dm @@ -43,17 +43,13 @@ /obj/effect/timestop/proc/timestop() target = get_turf(src) playsound(src, 'sound/magic/timeparadox2.ogg', 75, TRUE, -1) - chronofield = make_field(/datum/proximity_monitor/advanced/timestop, list("current_range" = freezerange, "host" = src, "immune" = immune, "check_anti_magic" = check_anti_magic, "check_holy" = check_holy)) + chronofield = new (src, freezerange, TRUE, immune, check_anti_magic, check_holy) QDEL_IN(src, duration) /obj/effect/timestop/magic check_anti_magic = TRUE /datum/proximity_monitor/advanced/timestop - name = "chronofield" - setup_field_turfs = TRUE - field_shape = FIELD_SHAPE_RADIUS_SQUARE - requires_processing = TRUE var/list/immune = list() var/list/frozen_things = list() var/list/frozen_mobs = list() //cached separately for processing @@ -64,12 +60,21 @@ var/static/list/global_frozen_atoms = list() +/datum/proximity_monitor/advanced/timestop/New(atom/_host, range, _ignore_if_not_on_turf = TRUE, list/immune, check_anti_magic, check_holy) + ..() + src.immune = immune + src.check_anti_magic = check_anti_magic + src.check_holy = check_holy + recalculate_field() + START_PROCESSING(SSfastprocess, src) + /datum/proximity_monitor/advanced/timestop/Destroy() unfreeze_all() + STOP_PROCESSING(SSfastprocess, src) return ..() -/datum/proximity_monitor/advanced/timestop/field_turf_crossed(atom/movable/AM) - freeze_atom(AM) +/datum/proximity_monitor/advanced/timestop/field_turf_crossed(atom/movable/movable, turf/location) + freeze_atom(movable) /datum/proximity_monitor/advanced/timestop/proc/freeze_atom(atom/movable/A) if(immune[A] || global_frozen_atoms[A] || !istype(A)) @@ -167,10 +172,10 @@ m.Stun(20, ignore_canstun = TRUE) /datum/proximity_monitor/advanced/timestop/setup_field_turf(turf/T) + . = ..() for(var/i in T.contents) freeze_atom(i) freeze_turf(T) - return ..() /datum/proximity_monitor/advanced/timestop/proc/freeze_projectile(obj/projectile/P) diff --git a/code/datums/proximity_monitor/proximity_monitor.dm b/code/datums/proximity_monitor/proximity_monitor.dm new file mode 100644 index 00000000000..6bc78a39c83 --- /dev/null +++ b/code/datums/proximity_monitor/proximity_monitor.dm @@ -0,0 +1,78 @@ +/datum/proximity_monitor + ///The atom we are tracking + var/atom/host + ///The atom that will receive HasProximity calls. + var/atom/hasprox_receiver + ///The range of the proximity monitor. Things moving wihin it will trigger HasProximity calls. + var/current_range + ///If we don't check turfs in range if the host's loc isn't a turf + var/ignore_if_not_on_turf + ///The signals of the connect range component, needed to monitor the turfs in range. + var/static/list/loc_connections = list( + COMSIG_ATOM_ENTERED = .proc/on_entered, + COMSIG_ATOM_EXITED =.proc/on_uncrossed, + ) + +/datum/proximity_monitor/New(atom/_host, range, _ignore_if_not_on_turf = TRUE) + ignore_if_not_on_turf = _ignore_if_not_on_turf + current_range = range + set_host(_host) + +/datum/proximity_monitor/proc/set_host(atom/new_host, atom/new_receiver) + if(new_host == host) + return + if(host) //No need to delete the connect range and containers comps. They'll be updated with the new tracked host. + UnregisterSignal(host, list(COMSIG_MOVABLE_MOVED, COMSIG_PARENT_QDELETING)) + if(hasprox_receiver) + UnregisterSignal(hasprox_receiver, COMSIG_PARENT_QDELETING) + if(new_receiver) + hasprox_receiver = new_receiver + if(new_receiver != new_host) + RegisterSignal(new_receiver, COMSIG_PARENT_QDELETING, .proc/on_host_or_receiver_del) + else if(hasprox_receiver == host) //Default case + hasprox_receiver = new_host + host = new_host + RegisterSignal(new_host, COMSIG_PARENT_QDELETING, .proc/on_host_or_receiver_del) + var/static/list/containers_connections = list(COMSIG_MOVABLE_MOVED = .proc/on_moved) + AddComponent(/datum/component/connect_containers, host, containers_connections) + RegisterSignal(host, COMSIG_MOVABLE_MOVED, .proc/on_moved) + set_range(current_range, TRUE) + +/datum/proximity_monitor/proc/on_host_or_receiver_del(datum/source) + SIGNAL_HANDLER + qdel(src) + +/datum/proximity_monitor/Destroy() + host = null + hasprox_receiver = null + return ..() + +/datum/proximity_monitor/proc/set_range(range, force_rebuild = FALSE) + if(!force_rebuild && range == current_range) + return FALSE + . = TRUE + current_range = range + + //If the connect_range component exists already, this will just update its range. No errors or duplicates. + AddComponent(/datum/component/connect_range, host, loc_connections, range, !ignore_if_not_on_turf) + +/datum/proximity_monitor/proc/on_moved(atom/movable/source, atom/old_loc) + SIGNAL_HANDLER + if(source == host) + hasprox_receiver?.HasProximity(host) + +/datum/proximity_monitor/proc/set_ignore_if_not_on_turf(does_ignore = TRUE) + if(ignore_if_not_on_turf == does_ignore) + return + ignore_if_not_on_turf = does_ignore + //Update the ignore_if_not_on_turf + AddComponent(/datum/component/connect_range, host, loc_connections, current_range, ignore_if_not_on_turf) + +/datum/proximity_monitor/proc/on_uncrossed() + SIGNAL_HANDLER + return //Used by the advanced subtype for effect fields. + +/datum/proximity_monitor/proc/on_entered(atom/source, atom/movable/arrived) + SIGNAL_HANDLER + if(source != host) + hasprox_receiver?.HasProximity(arrived) diff --git a/code/datums/wires/explosive.dm b/code/datums/wires/explosive.dm index 0a1eeab645e..398d9352288 100644 --- a/code/datums/wires/explosive.dm +++ b/code/datums/wires/explosive.dm @@ -46,9 +46,10 @@ var/obj/item/assembly/timer/T = S G.det_time = T.saved_time*10 else if(istype(S,/obj/item/assembly/prox_sensor)) - var/obj/item/grenade/chem_grenade/G = holder - G.landminemode = S - S.proximity_monitor.wire = TRUE + var/obj/item/assembly/prox_sensor/sensor = S + var/obj/item/grenade/chem_grenade/grenade = holder + grenade.landminemode = sensor + sensor.proximity_monitor.set_ignore_if_not_on_turf(FALSE) fingerprint = S.fingerprintslast return ..() diff --git a/code/game/atoms.dm b/code/game/atoms.dm index b9193ca92eb..07c02ec6231 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -56,8 +56,6 @@ ///overlays managed by [update_overlays][/atom/proc/update_overlays] to prevent removing overlays that weren't added by the same proc. Single items are stored on their own, not in a list. var/list/managed_overlays - ///Proximity monitor associated with this atom - var/datum/proximity_monitor/proximity_monitor ///Cooldown tick timer for buckle messages var/buckle_message_cooldown = 0 ///Last fingerprints to touch this atom diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index a7a67e0c1a7..ce1e3c5a7c0 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -106,7 +106,6 @@ /atom/movable/Destroy(force) - QDEL_NULL(proximity_monitor) QDEL_NULL(language_holder) QDEL_NULL(em_block) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index b2810a2fc4d..0c2cd199971 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -42,6 +42,8 @@ var/internal_light = TRUE //Whether it can light up when an AI views it ///Represents a signel source of camera alarms about movement or camera tampering var/datum/alarm_handler/alarm_manager + ///Proximity monitor associated with this atom, for motion sensitive cameras. + var/datum/proximity_monitor/proximity_monitor MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera, 0) MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/autoname, 0) @@ -101,7 +103,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/camera/xray, 0) network -= i network += "[port.id]_[i]" -/obj/machinery/proc/create_prox_monitor() +/obj/machinery/camera/proc/create_prox_monitor() if(!proximity_monitor) proximity_monitor = new(src, 1) diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index 32df12a4c83..58418b03317 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -79,7 +79,7 @@ /obj/machinery/camera/motion/thunderdome/Initialize(mapload) . = ..() - proximity_monitor.SetRange(7) + proximity_monitor.set_range(7) /obj/machinery/camera/motion/thunderdome/HasProximity(atom/movable/AM as mob|obj) if (!isliving(AM) || get_area(AM) != get_area(src)) diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index 2ed8bccdaaf..30fde7ea0eb 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -30,6 +30,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/flasher, 26) light_system = MOVABLE_LIGHT //Used as a flash here. light_range = FLASH_LIGHT_RANGE light_on = FALSE + ///Proximity monitor associated with this atom, needed for proximity checks. + var/datum/proximity_monitor/proximity_monitor /obj/machinery/flasher/Initialize(mapload, ndir = 0, built = 0) . = ..() // ..() is EXTREMELY IMPORTANT, never forget to add it @@ -180,13 +182,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/flasher, 26) add_overlay("[base_icon_state]-s") set_anchored(TRUE) power_change() - proximity_monitor.SetRange(range) + proximity_monitor.set_range(range) else to_chat(user, span_notice("[src] can now be moved.")) cut_overlays() set_anchored(FALSE) power_change() - proximity_monitor.SetRange(0) + proximity_monitor.set_range(0) else return ..() diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm index ac8b70675f5..2d488535b48 100644 --- a/code/game/machinery/hologram.dm +++ b/code/game/machinery/hologram.dm @@ -103,6 +103,8 @@ Possible to do for anyone motivated enough: resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF flags_1 = NODECONSTRUCT_1 on_network = FALSE + ///Proximity monitor associated with this atom, needed for proximity checks. + var/datum/proximity_monitor/proximity_monitor var/proximity_range = 1 /obj/machinery/holopad/tutorial/Initialize(mapload) diff --git a/code/game/objects/effects/anomalies.dm b/code/game/objects/effects/anomalies.dm index 7488420a3bc..bf49e6a18b8 100644 --- a/code/game/objects/effects/anomalies.dm +++ b/code/game/objects/effects/anomalies.dm @@ -170,14 +170,14 @@ boing = 0 /obj/effect/anomaly/grav/high - var/grav_field + var/datum/proximity_monitor/advanced/gravity/grav_field /obj/effect/anomaly/grav/high/Initialize(mapload, new_lifespan) . = ..() INVOKE_ASYNC(src, .proc/setup_grav_field) /obj/effect/anomaly/grav/high/proc/setup_grav_field() - grav_field = make_field(/datum/proximity_monitor/advanced/gravity, list("current_range" = 7, "host" = src, "gravity_value" = rand(0,3))) + grav_field = new(src, 7, TRUE, rand(0, 3)) /obj/effect/anomaly/grav/high/Destroy() QDEL_NULL(grav_field) diff --git a/code/game/objects/effects/proximity.dm b/code/game/objects/effects/proximity.dm deleted file mode 100644 index ad2b829f884..00000000000 --- a/code/game/objects/effects/proximity.dm +++ /dev/null @@ -1,129 +0,0 @@ -/datum/proximity_monitor - var/atom/host //the atom we are tracking - var/atom/hasprox_receiver //the atom that will receive HasProximity calls. - var/atom/last_host_loc - var/list/checkers //list of /obj/effect/abstract/proximity_checkers - var/current_range - var/ignore_if_not_on_turf //don't check turfs in range if the host's loc isn't a turf - var/wire = FALSE - -/datum/proximity_monitor/New(atom/_host, range, _ignore_if_not_on_turf = TRUE) - checkers = list() - last_host_loc = _host.loc - ignore_if_not_on_turf = _ignore_if_not_on_turf - current_range = range - SetHost(_host) - -/datum/proximity_monitor/proc/SetHost(atom/H,atom/R) - if(H == host) - return - if(host) - UnregisterSignal(host, COMSIG_MOVABLE_MOVED) - if(R) - hasprox_receiver = R - else if(hasprox_receiver == host) //Default case - hasprox_receiver = H - host = H - RegisterSignal(host, COMSIG_MOVABLE_MOVED, .proc/HandleMove) - last_host_loc = host.loc - SetRange(current_range,TRUE) - -/datum/proximity_monitor/Destroy() - host = null - last_host_loc = null - hasprox_receiver = null - QDEL_LAZYLIST(checkers) - return ..() - -/datum/proximity_monitor/proc/HandleMove() - SIGNAL_HANDLER - - var/atom/_host = host - var/atom/new_host_loc = _host.loc - if(last_host_loc != new_host_loc) - last_host_loc = new_host_loc //hopefully this won't cause GC issues with containers - var/curr_range = current_range - SetRange(curr_range, TRUE) - if(curr_range) - testing("HasProx: [host] -> [host]") - hasprox_receiver.HasProximity(host) //if we are processing, we're guaranteed to be a movable - -/datum/proximity_monitor/proc/SetRange(range, force_rebuild = FALSE) - if(!force_rebuild && range == current_range) - return FALSE - . = TRUE - - LAZYINITLIST(checkers) - - current_range = range - - var/list/checkers_local = checkers - var/old_checkers_len = checkers_local.len - - var/atom/_host = host - - var/atom/loc_to_use = ignore_if_not_on_turf ? _host.loc : get_turf(_host) - if(wire && !isturf(loc_to_use)) //it makes assemblies attached on wires work - loc_to_use = get_turf(loc_to_use) - if(!isturf(loc_to_use)) //only check the host's loc - if(range) - var/obj/effect/abstract/proximity_checker/pc - if(old_checkers_len) - pc = checkers_local[old_checkers_len] - --checkers_local.len - QDEL_LAZYLIST(checkers_local) - else - pc = new(loc_to_use, src) - - checkers_local += pc //only check the host's loc - return - - var/list/turfs = RANGE_TURFS(range, loc_to_use) - var/turfs_len = turfs.len - var/old_checkers_used = min(turfs_len, old_checkers_len) - - //reuse what we can - for(var/I in 1 to old_checkers_len) - if(I <= old_checkers_used) - var/obj/effect/abstract/proximity_checker/pc = checkers_local[I] - pc.forceMove(turfs[I]) - else - qdel(checkers_local[I]) //delete the leftovers - - if(old_checkers_len < turfs_len) - //create what we lack - for(var/I in (old_checkers_used + 1) to turfs_len) - checkers_local += new /obj/effect/abstract/proximity_checker(turfs[I], src) - else - checkers_local.Cut(old_checkers_used + 1, old_checkers_len) - -/obj/effect/abstract/proximity_checker - invisibility = INVISIBILITY_ABSTRACT - anchored = TRUE - var/datum/proximity_monitor/monitor - -/obj/effect/abstract/proximity_checker/Initialize(mapload, datum/proximity_monitor/_monitor) - . = ..() - if(_monitor) - monitor = _monitor - else - stack_trace("proximity_checker created without host") - return INITIALIZE_HINT_QDEL - var/static/list/loc_connections = list( - COMSIG_ATOM_ENTERED = .proc/on_entered, - COMSIG_ATOM_EXITED =.proc/on_uncrossed, - ) - AddElement(/datum/element/connect_loc, loc_connections) - -/obj/effect/abstract/proximity_checker/proc/on_uncrossed(datum/source, atom/movable/gone, direction) - SIGNAL_HANDLER - return - -/obj/effect/abstract/proximity_checker/Destroy() - LAZYREMOVE(monitor.checkers, src) - monitor = null - return ..() - -/obj/effect/abstract/proximity_checker/proc/on_entered(datum/source, atom/movable/AM) - SIGNAL_HANDLER - monitor?.hasprox_receiver?.HasProximity(AM) diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm index 8355eccaaf9..22d13cc562f 100644 --- a/code/game/objects/items/robot/robot_items.dm +++ b/code/game/objects/items/robot/robot_items.dm @@ -584,7 +584,7 @@ var/energy_recharge_cyborg_drain_coefficient = 0.4 var/cyborg_cell_critical_percentage = 0.05 var/mob/living/silicon/robot/host = null - var/datum/proximity_monitor/advanced/dampening_field + var/datum/proximity_monitor/advanced/peaceborg_dampener/dampening_field var/projectile_damage_coefficient = 0.5 /// Energy cost per tracked projectile damage amount per second var/projectile_damage_tick_ecost_coefficient = 10 @@ -642,10 +642,9 @@ /obj/item/borg/projectile_dampen/proc/activate_field() if(istype(dampening_field)) QDEL_NULL(dampening_field) - dampening_field = make_field(/datum/proximity_monitor/advanced/peaceborg_dampener, list("current_range" = field_radius, "host" = src, "projector" = src)) var/mob/living/silicon/robot/owner = get_host() - if(owner) - owner.model.allow_riding = FALSE + dampening_field = new(owner, field_radius, TRUE, src) + owner?.model.allow_riding = FALSE active = TRUE /obj/item/borg/projectile_dampen/proc/deactivate_field() @@ -682,11 +681,6 @@ /obj/item/borg/projectile_dampen/process(delta_time) process_recharge(delta_time) process_usage(delta_time) - update_location() - -/obj/item/borg/projectile_dampen/proc/update_location() - if(dampening_field) - dampening_field.HandleMove() /obj/item/borg/projectile_dampen/proc/process_usage(delta_time) var/usage = 0 diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index 7b34ea1122b..bc3b322f0dc 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -276,6 +276,8 @@ var/status = GROWING //can be GROWING, GROWN or BURST; all mutually exclusive layer = MOB_LAYER var/obj/item/clothing/mask/facehugger/child + ///Proximity monitor associated with this atom, needed for proximity checks. + var/datum/proximity_monitor/proximity_monitor /obj/structure/alien/egg/Initialize(mapload) . = ..() @@ -335,13 +337,13 @@ /obj/structure/alien/egg/proc/Grow() status = GROWN update_appearance() - proximity_monitor.SetRange(1) + proximity_monitor.set_range(1) //drops and kills the hugger if any is remaining /obj/structure/alien/egg/proc/Burst(kill = TRUE) if(status == GROWN || status == GROWING) status = BURSTING - proximity_monitor.SetRange(0) + proximity_monitor.set_range(0) update_appearance() flick("egg_opening", src) addtimer(CALLBACK(src, .proc/finish_bursting, kill), 15) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index f0bb5ddc6ef..a47c57342ca 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -353,12 +353,11 @@ GLOBAL_LIST_EMPTY(station_turfs) var/atom/firstbump var/canPassSelf = CanPass(mover, get_dir(src, mover)) if(canPassSelf || (mover.movement_type & PHASING)) - for(var/i in contents) + for(var/atom/movable/thing as anything in contents) if(QDELETED(mover)) return FALSE //We were deleted, do not attempt to proceed with movement. - if(i == mover || i == mover.loc) // Multi tile objects and moving out of other objects + if(thing == mover || thing == mover.loc) // Multi tile objects and moving out of other objects continue - var/atom/movable/thing = i if(!thing.Cross(mover)) if(QDELETED(mover)) //Mover deleted from Cross/CanPass, do not proceed. return FALSE diff --git a/code/modules/admin/verbs/secrets.dm b/code/modules/admin/verbs/secrets.dm index 0c358018819..34b9db1f44c 100644 --- a/code/modules/admin/verbs/secrets.dm +++ b/code/modules/admin/verbs/secrets.dm @@ -156,7 +156,7 @@ GLOBAL_DATUM(everyone_a_traitor, /datum/everyone_is_a_traitor_controller) for(var/mob/living/mob in thunderdome) qdel(mob) //Clear mobs for(var/obj/obj in thunderdome) - if(!istype(obj, /obj/machinery/camera) && !istype(obj, /obj/effect/abstract/proximity_checker)) + if(!istype(obj, /obj/machinery/camera)) qdel(obj) //Clear objects var/area/template = GLOB.areas_by_type[/area/tdome/arena_source] diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index b7da48b3432..c1c4cecaffd 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -11,6 +11,8 @@ var/time = 20 var/sensitivity = 1 var/hearing_range = 3 + ///Proximity monitor associated with this atom, needed for it to work. + var/datum/proximity_monitor/proximity_monitor /obj/item/assembly/prox_sensor/Initialize(mapload) . = ..() @@ -40,19 +42,19 @@ if(!.) return else - proximity_monitor.SetHost(src,src) + proximity_monitor.set_host(src, src) /obj/item/assembly/prox_sensor/toggle_secure() secured = !secured if(!secured) if(scanning) toggle_scan() - proximity_monitor.SetHost(src,src) + proximity_monitor.set_host(src, src) timing = FALSE STOP_PROCESSING(SSobj, src) else START_PROCESSING(SSobj, src) - proximity_monitor.SetHost(loc,src) + proximity_monitor.set_host(loc,src) update_appearance() return secured @@ -84,13 +86,13 @@ if(!secured) return FALSE scanning = scan - proximity_monitor.SetRange(scanning ? sensitivity : 0) + proximity_monitor.set_range(scanning ? sensitivity : 0) update_appearance() /obj/item/assembly/prox_sensor/proc/sensitivity_change(value) var/sense = min(max(sensitivity + value, 0), 5) sensitivity = sense - if(scanning && proximity_monitor.SetRange(sense)) + if(scanning && proximity_monitor.set_range(sense)) sense() /obj/item/assembly/prox_sensor/update_appearance() diff --git a/code/modules/fields/fields.dm b/code/modules/fields/fields.dm deleted file mode 100644 index 69c166c5207..00000000000 --- a/code/modules/fields/fields.dm +++ /dev/null @@ -1,324 +0,0 @@ - -//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. -//If there's any way to make this less CPU intensive than I've managed, gimme a call or do it yourself! - kevinz000 - -//Field shapes -#define FIELD_NO_SHAPE 0 //Does not update turfs automatically -#define FIELD_SHAPE_RADIUS_SQUARE 1 //Uses current_range and square_depth_up/down -#define FIELD_SHAPE_CUSTOM_SQUARE 2 //Uses square_height and square_width and square_depth_up/down - -//Proc to make fields. make_field(field_type, field_params_in_associative_list) -/proc/make_field(field_type, list/field_params, override_checks = FALSE, start_field = TRUE) - var/datum/proximity_monitor/advanced/F = new field_type() - if(!F.assume_params(field_params) && !override_checks) - QDEL_NULL(F) - if(!F.check_variables() && !override_checks) - QDEL_NULL(F) - if(start_field && (F || override_checks)) - F.begin_field() - return F - -/datum/proximity_monitor/advanced - var/name = "\improper Energy Field" - //Field setup specifications - var/field_shape = FIELD_NO_SHAPE - var/square_height = 0 - var/square_width = 0 - var/square_depth_up = 0 - var/square_depth_down = 0 - //Processing - var/process_inner_turfs = FALSE //Don't do this unless it's absolutely necessary - var/process_edge_turfs = FALSE //Don't do this either unless it's absolutely necessary, you can just track what things are inside manually or on the initial setup. - var/requires_processing = FALSE - var/setup_edge_turfs = FALSE //Setup edge turfs/all field turfs. Set either or both to ON when you need it, it's defaulting to off unless you do to save CPU. - var/setup_field_turfs = FALSE - var/use_host_turf = FALSE //For fields from items carried on mobs to check turf instead of loc... - - var/list/turf/field_turfs = list() - var/list/turf/edge_turfs = list() - var/list/turf/field_turfs_new = list() - var/list/turf/edge_turfs_new = list() - -/datum/proximity_monitor/advanced/Destroy() - full_cleanup() - STOP_PROCESSING(SSfields, src) - return ..() - -/datum/proximity_monitor/advanced/proc/assume_params(list/field_params) - var/pass_check = TRUE - for(var/param in field_params) - if(vars[param] || isnull(vars[param]) || (param in vars)) - vars[param] = field_params[param] - else - pass_check = FALSE - return pass_check - -/datum/proximity_monitor/advanced/proc/check_variables() - var/pass = TRUE - if(field_shape == FIELD_NO_SHAPE) //If you're going to make a manually updated field you shouldn't be using automatic checks so don't. - pass = FALSE - if(current_range < 0 || square_height < 0 || square_width < 0 || square_depth_up < 0 || square_depth_down < 0) - pass = FALSE - if(!istype(host)) - pass = FALSE - return pass - -/datum/proximity_monitor/advanced/process() - if(process_inner_turfs) - for(var/turf/T in field_turfs) - process_inner_turf(T) - CHECK_TICK //Really crappy lagchecks, needs improvement once someone starts using processed fields. - if(process_edge_turfs) - for(var/turf/T in edge_turfs) - process_edge_turf(T) - CHECK_TICK //Same here. - -/datum/proximity_monitor/advanced/proc/process_inner_turf(turf/T) - -/datum/proximity_monitor/advanced/proc/process_edge_turf(turf/T) - -/datum/proximity_monitor/advanced/New(atom/_host, range, _ignore_if_not_on_turf = TRUE) - if(requires_processing) - START_PROCESSING(SSfields, src) - -/datum/proximity_monitor/advanced/proc/begin_field() - setup_field() - post_setup_field() - -/datum/proximity_monitor/advanced/proc/full_cleanup() //Full cleanup for when you change something that would require complete resetting. - for(var/turf/T in edge_turfs) - cleanup_edge_turf(T) - for(var/turf/T in field_turfs) - cleanup_field_turf(T) - -/datum/proximity_monitor/advanced/proc/check_movement() - if(!use_host_turf) - if(host.loc != last_host_loc) - last_host_loc = host.loc - return TRUE - else - if(get_turf(host) != last_host_loc) - last_host_loc = get_turf(host) - return TRUE - return FALSE - -/datum/proximity_monitor/advanced/proc/recalculate_field(ignore_movement_check = FALSE) //Call every time the field moves (done automatically if you use update_center) or a setup specification is changed. - if(!(ignore_movement_check || check_movement()) && (field_shape != FIELD_NO_SHAPE)) - return - update_new_turfs() - var/list/turf/needs_setup = field_turfs_new.Copy() - if(setup_field_turfs) - for(var/turf/T in field_turfs) - if(!(T in needs_setup)) - cleanup_field_turf(T) - else - needs_setup -= T - CHECK_TICK - for(var/turf/T in needs_setup) - setup_field_turf(T) - CHECK_TICK - if(setup_edge_turfs) - for(var/turf/T in edge_turfs) - cleanup_edge_turf(T) - CHECK_TICK - for(var/turf/T in edge_turfs_new) - setup_edge_turf(T) - CHECK_TICK - -/datum/proximity_monitor/advanced/proc/field_turf_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F, border_dir) - return TRUE - -/datum/proximity_monitor/advanced/proc/field_turf_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F) - return TRUE - -/datum/proximity_monitor/advanced/proc/field_turf_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_turf/F) - return TRUE - -/datum/proximity_monitor/advanced/proc/field_edge_canpass(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F, border_dir) - return TRUE - -/datum/proximity_monitor/advanced/proc/field_edge_crossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F) - return TRUE - -/datum/proximity_monitor/advanced/proc/field_edge_uncrossed(atom/movable/AM, obj/effect/abstract/proximity_checker/advanced/field_edge/F) - return TRUE - -/datum/proximity_monitor/advanced/HandleMove() - var/atom/_host = host - var/atom/new_host_loc = _host.loc - if(last_host_loc != new_host_loc) - INVOKE_ASYNC(src, .proc/recalculate_field) - -/datum/proximity_monitor/advanced/proc/post_setup_field() - -/datum/proximity_monitor/advanced/proc/setup_field() - update_new_turfs() - if(setup_field_turfs) - for(var/turf/T in field_turfs_new) - setup_field_turf(T) - CHECK_TICK - if(setup_edge_turfs) - for(var/turf/T in edge_turfs_new) - setup_edge_turf(T) - CHECK_TICK - -/datum/proximity_monitor/advanced/proc/cleanup_field_turf(turf/T) - qdel(field_turfs[T]) - field_turfs -= T - -/datum/proximity_monitor/advanced/proc/cleanup_edge_turf(turf/T) - qdel(edge_turfs[T]) - edge_turfs -= T - -/datum/proximity_monitor/advanced/proc/setup_field_turf(turf/T) - field_turfs[T] = new /obj/effect/abstract/proximity_checker/advanced/field_turf(T, src) - -/datum/proximity_monitor/advanced/proc/setup_edge_turf(turf/T) - edge_turfs[T] = new /obj/effect/abstract/proximity_checker/advanced/field_edge(T, src) - -/datum/proximity_monitor/advanced/proc/update_new_turfs() - if(!istype(host)) - return FALSE - var/turf/center = get_turf(host) - field_turfs_new = list() - edge_turfs_new = list() - switch(field_shape) - if(FIELD_NO_SHAPE) - return FALSE - if(FIELD_SHAPE_RADIUS_SQUARE) - for(var/turf/T in block(locate(center.x-current_range,center.y-current_range,center.z-square_depth_down),locate(center.x+current_range, center.y+current_range,center.z+square_depth_up))) - field_turfs_new += T - edge_turfs_new = field_turfs_new.Copy() - if(current_range >= 1) - var/list/turf/center_turfs = list() - for(var/turf/T in block(locate(center.x-current_range+1,center.y-current_range+1,center.z-square_depth_down),locate(center.x+current_range-1, center.y+current_range-1,center.z+square_depth_up))) - center_turfs += T - for(var/turf/T in center_turfs) - edge_turfs_new -= T - if(FIELD_SHAPE_CUSTOM_SQUARE) - for(var/turf/T in block(locate(center.x-square_width,center.y-square_height,center.z-square_depth_down),locate(center.x+square_width, center.y+square_height,center.z+square_depth_up))) - field_turfs_new += T - edge_turfs_new = field_turfs_new.Copy() - if(square_height >= 1 && square_width >= 1) - var/list/turf/center_turfs = list() - for(var/turf/T in block(locate(center.x-square_width+1,center.y-square_height+1,center.z-square_depth_down),locate(center.x+square_width-1, center.y+square_height-1,center.z+square_depth_up))) - center_turfs += T - for(var/turf/T in center_turfs) - edge_turfs_new -= T - -//Gets edge direction/corner, only works with square radius/WDH fields! -/datum/proximity_monitor/advanced/proc/get_edgeturf_direction(turf/T, turf/center_override = null) - var/turf/checking_from = get_turf(host) - if(istype(center_override)) - checking_from = center_override - if(field_shape != FIELD_SHAPE_RADIUS_SQUARE && field_shape != FIELD_SHAPE_CUSTOM_SQUARE) - return - if(!(T in edge_turfs)) - return - switch(field_shape) - if(FIELD_SHAPE_RADIUS_SQUARE) - if(((T.x == (checking_from.x + current_range)) || (T.x == (checking_from.x - current_range))) && ((T.y == (checking_from.y + current_range)) || (T.y == (checking_from.y - current_range)))) - return get_dir(checking_from, T) - if(T.x == (checking_from.x + current_range)) - return EAST - if(T.x == (checking_from.x - current_range)) - return WEST - if(T.y == (checking_from.y - current_range)) - return SOUTH - if(T.y == (checking_from.y + current_range)) - return NORTH - if(FIELD_SHAPE_CUSTOM_SQUARE) - if(((T.x == (checking_from.x + square_width)) || (T.x == (checking_from.x - square_width))) && ((T.y == (checking_from.y + square_height)) || (T.y == (checking_from.y - square_height)))) - return get_dir(checking_from, T) - if(T.x == (checking_from.x + square_width)) - return EAST - if(T.x == (checking_from.x - square_width)) - return WEST - if(T.y == (checking_from.y - square_height)) - return SOUTH - if(T.y == (checking_from.y + square_height)) - return NORTH - -//DEBUG FIELDS -/datum/proximity_monitor/advanced/debug - name = "\improper Color Matrix Field" - field_shape = FIELD_SHAPE_RADIUS_SQUARE - current_range = 5 - var/set_fieldturf_color = "#aaffff" - var/set_edgeturf_color = "#ffaaff" - setup_field_turfs = TRUE - setup_edge_turfs = TRUE - - -/datum/proximity_monitor/advanced/debug/setup_edge_turf(turf/T) - T.color = set_edgeturf_color - ..() - -/datum/proximity_monitor/advanced/debug/cleanup_edge_turf(turf/T) - T.color = initial(T.color) - ..() - if(T in field_turfs) - T.color = set_fieldturf_color - -/datum/proximity_monitor/advanced/debug/setup_field_turf(turf/T) - T.color = set_fieldturf_color - ..() - -/datum/proximity_monitor/advanced/debug/cleanup_field_turf(turf/T) - T.color = initial(T.color) - ..() - -//DEBUG FIELD ITEM -/obj/item/multitool/field_debug - name = "strange multitool" - desc = "Seems to project a colored field!" - var/list/field_params = list("field_shape" = FIELD_SHAPE_RADIUS_SQUARE, "current_range" = 5, "set_fieldturf_color" = "#aaffff", "set_edgeturf_color" = "#ffaaff") - var/field_type = /datum/proximity_monitor/advanced/debug - var/operating = FALSE - var/datum/proximity_monitor/advanced/current = null - var/mob/listeningTo - -/obj/item/multitool/field_debug/Initialize(mapload) - . = ..() - START_PROCESSING(SSobj, src) - -/obj/item/multitool/field_debug/Destroy() - STOP_PROCESSING(SSobj, src) - QDEL_NULL(current) - listeningTo = null - return ..() - -/obj/item/multitool/field_debug/proc/setup_debug_field() - var/list/new_params = field_params.Copy() - new_params["host"] = src - current = make_field(field_type, new_params) - -/obj/item/multitool/field_debug/attack_self(mob/user) - operating = !operating - to_chat(user, span_notice("You turn [src] [operating? "on":"off"].")) - UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED) - listeningTo = null - if(!istype(current) && operating) - RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move) - listeningTo = user - setup_debug_field() - else if(!operating) - QDEL_NULL(current) - -/obj/item/multitool/field_debug/dropped() - . = ..() - if(listeningTo) - UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED) - listeningTo = null - -/obj/item/multitool/field_debug/proc/on_mob_move() - SIGNAL_HANDLER - - check_turf(get_turf(src)) - -/obj/item/multitool/field_debug/process() - check_turf(get_turf(src)) - -/obj/item/multitool/field_debug/proc/check_turf(turf/T) - current.HandleMove() diff --git a/code/modules/fields/turf_objects.dm b/code/modules/fields/turf_objects.dm deleted file mode 100644 index 3ecea11eeb1..00000000000 --- a/code/modules/fields/turf_objects.dm +++ /dev/null @@ -1,70 +0,0 @@ - -/obj/effect/abstract/proximity_checker/advanced - name = "field" - desc = "Why can you see energy fields?!" - icon = null - icon_state = null - alpha = 0 - invisibility = INVISIBILITY_ABSTRACT - flags_1 = ON_BORDER_1 - mouse_opacity = MOUSE_OPACITY_TRANSPARENT - var/datum/proximity_monitor/advanced/parent = null - -/obj/effect/abstract/proximity_checker/advanced/Initialize(mapload, _monitor) - if(_monitor) - parent = _monitor - . = ..() - -/obj/effect/abstract/proximity_checker/advanced/center - name = "field anchor" - desc = "No." - -/obj/effect/abstract/proximity_checker/advanced/field_turf - name = "energy field" - desc = "Get off my turf!" - -/obj/effect/abstract/proximity_checker/advanced/field_turf/CanAllowThrough(atom/movable/mover, border_dir) - . = ..() - if(parent) - return parent.field_turf_canpass(mover, src, border_dir) - -/obj/effect/abstract/proximity_checker/advanced/field_turf/on_entered(datum/source, atom/movable/AM) - . = ..() - if(parent) - return parent.field_turf_crossed(AM, src) - return TRUE - -/obj/effect/abstract/proximity_checker/advanced/field_turf/on_uncrossed(datum/source, atom/movable/gone, direction) - . = ..() - if(parent) - return parent.field_turf_uncrossed(gone, src) - return TRUE - -/obj/effect/abstract/proximity_checker/advanced/field_edge - name = "energy field edge" - desc = "Edgy description here." - -/obj/effect/abstract/proximity_checker/advanced/field_edge/CanAllowThrough(atom/movable/mover, border_dir) - . = ..() - if(parent) - return parent.field_edge_canpass(mover, src, border_dir) - -/obj/effect/abstract/proximity_checker/advanced/field_edge/on_entered(datum/source, atom/movable/AM) - . = ..() - if(parent) - return parent.field_edge_crossed(AM, src) - return TRUE - -/obj/effect/abstract/proximity_checker/advanced/field_edge/on_uncrossed(datum/source, atom/movable/gone, direction) - if(parent) - return parent.field_edge_uncrossed(gone, src) - return TRUE - -/proc/is_turf_in_field(turf/T, datum/proximity_monitor/advanced/F) //Looking for ways to optimize this! - for(var/obj/effect/abstract/proximity_checker/advanced/O in T) - if(istype(O, /obj/effect/abstract/proximity_checker/advanced/field_edge)) - if(O.parent == F) - return FIELD_EDGE - if(O.parent == F) - return FIELD_TURF - return FALSE diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm index c3a14da09be..d533c730e2f 100644 --- a/code/modules/mining/machine_processing.dm +++ b/code/modules/mining/machine_processing.dm @@ -129,6 +129,8 @@ var/datum/material/selected_material = null var/selected_alloy = null var/datum/techweb/stored_research + ///Proximity monitor associated with this atom, needed for proximity checks. + var/datum/proximity_monitor/proximity_monitor /obj/machinery/mineral/processing_unit/Initialize(mapload) . = ..() diff --git a/code/modules/mining/machine_stacking.dm b/code/modules/mining/machine_stacking.dm index 90f51edb688..52ee80ae993 100644 --- a/code/modules/mining/machine_stacking.dm +++ b/code/modules/mining/machine_stacking.dm @@ -91,6 +91,8 @@ var/stack_amt = 50 //amount to stack before releassing var/datum/component/remote_materials/materials var/force_connect = FALSE + ///Proximity monitor associated with this atom, needed for proximity checks. + var/datum/proximity_monitor/proximity_monitor /obj/machinery/mineral/stacking_machine/Initialize(mapload) . = ..() diff --git a/code/modules/power/gravitygenerator.dm b/code/modules/power/gravitygenerator.dm index 90db7b3f6f9..de4e694822e 100644 --- a/code/modules/power/gravitygenerator.dm +++ b/code/modules/power/gravitygenerator.dm @@ -308,7 +308,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne investigate_log("was brought online and is now producing gravity for this level.", INVESTIGATE_GRAVITY) message_admins("The gravity generator was brought online [ADMIN_VERBOSEJMP(src)]") shake_everyone() - gravity_field = make_field(/datum/proximity_monitor/advanced/gravity, list("current_range" = 2, "host" = src, "gravity_value" = 6)) + gravity_field = new(src, 2, TRUE, 6) complete_state_update() diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm index 1883b4cd694..63bbb0a31b3 100644 --- a/code/modules/shuttle/on_move.dm +++ b/code/modules/shuttle/on_move.dm @@ -119,8 +119,6 @@ All ShuttleMove procs go here update_light() if(rotation) shuttleRotate(rotation) - if(proximity_monitor) - proximity_monitor.HandleMove() update_parallax_contents() @@ -387,7 +385,3 @@ All ShuttleMove procs go here /obj/docking_port/stationary/public_mining_dock/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) id = "mining_public" //It will not move with the base, but will become enabled as a docking point. - -/obj/effect/abstract/proximity_checker/onShuttleMove(turf/newT, turf/oldT, list/movement_force, move_dir, obj/docking_port/stationary/old_dock, obj/docking_port/mobile/moving_dock) - //timer so it only happens once - addtimer(CALLBACK(monitor, /datum/proximity_monitor/proc/SetRange, monitor.current_range, TRUE), 0, TIMER_UNIQUE) diff --git a/code/modules/unit_tests/create_and_destroy.dm b/code/modules/unit_tests/create_and_destroy.dm index 01e197a42a5..bc0654bf294 100644 --- a/code/modules/unit_tests/create_and_destroy.dm +++ b/code/modules/unit_tests/create_and_destroy.dm @@ -33,8 +33,6 @@ ignore += typesof(/obj/item/modular_computer/tablet/integrated) //This one demands a computer, ditto ignore += typesof(/obj/item/modular_computer/processor) - //Needs special input, let's be nice - ignore += typesof(/obj/effect/abstract/proximity_checker) //Very finiky, blacklisting to make things easier ignore += typesof(/obj/item/poster/wanted) //We can't pass a mind into this diff --git a/tgstation.dme b/tgstation.dme index bf24cf2a4f8..8d071ac71ab 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -485,7 +485,6 @@ #include "code\controllers\subsystem\processing\clock_component.dm" #include "code\controllers\subsystem\processing\conveyors.dm" #include "code\controllers\subsystem\processing\fastprocess.dm" -#include "code\controllers\subsystem\processing\fields.dm" #include "code\controllers\subsystem\processing\fluids.dm" #include "code\controllers\subsystem\processing\greyscale.dm" #include "code\controllers\subsystem\processing\instruments.dm" @@ -637,7 +636,9 @@ #include "code\datums\components\clothing_fov_visor.dm" #include "code\datums\components\codeword_hearing.dm" #include "code\datums\components\combustible_flooder.dm" +#include "code\datums\components\connect_containers.dm" #include "code\datums\components\connect_loc_behalf.dm" +#include "code\datums\components\connect_range.dm" #include "code\datums\components\construction.dm" #include "code\datums\components\cracked.dm" #include "code\datums\components\creamed.dm" @@ -1005,6 +1006,11 @@ #include "code\datums\mutations\touch.dm" #include "code\datums\mutations\holy_mutation\burdened.dm" #include "code\datums\mutations\holy_mutation\honorbound.dm" +#include "code\datums\proximity_monitor\field.dm" +#include "code\datums\proximity_monitor\proximity_monitor.dm" +#include "code\datums\proximity_monitor\fields\gravity.dm" +#include "code\datums\proximity_monitor\fields\peaceborg_dampener.dm" +#include "code\datums\proximity_monitor\fields\timestop.dm" #include "code\datums\quirks\_quirk.dm" #include "code\datums\quirks\good.dm" #include "code\datums\quirks\negative.dm" @@ -1260,7 +1266,6 @@ #include "code\game\objects\effects\phased_mob.dm" #include "code\game\objects\effects\portals.dm" #include "code\game\objects\effects\powerup.dm" -#include "code\game\objects\effects\proximity.dm" #include "code\game\objects\effects\spiderwebs.dm" #include "code\game\objects\effects\step_triggers.dm" #include "code\game\objects\effects\wanted_poster.dm" @@ -2543,11 +2548,6 @@ #include "code\modules\explorer_drone\exploration_events\fluff.dm" #include "code\modules\explorer_drone\exploration_events\resource.dm" #include "code\modules\explorer_drone\exploration_events\trader.dm" -#include "code\modules\fields\fields.dm" -#include "code\modules\fields\gravity.dm" -#include "code\modules\fields\peaceborg_dampener.dm" -#include "code\modules\fields\timestop.dm" -#include "code\modules\fields\turf_objects.dm" #include "code\modules\flufftext\Dreaming.dm" #include "code\modules\flufftext\Hallucination.dm" #include "code\modules\food_and_drinks\food.dm"