diff --git a/code/__defines/flags.dm b/code/__defines/flags.dm
index e59dac70c5..2ff8f44dba 100644
--- a/code/__defines/flags.dm
+++ b/code/__defines/flags.dm
@@ -29,8 +29,7 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define OPENCONTAINER (1<<4) // Is an open container for chemistry purposes.
#define PHORONGUARD (1<<5) // Does not get contaminated by phoron.
#define NOREACT (1<<6) // Reagents don't react inside this container.
-#define PROXMOVE (1<<7)// Does this object require proximity checking in Enter()?
-#define OVERLAY_QUEUED (1<<8)// Atom queued to SSoverlay for COMPILE_OVERLAYS
+#define OVERLAY_QUEUED (1<<7)// Atom queued to SSoverlay for COMPILE_OVERLAYS
//Flags for items (equipment) - Used in /obj/item/var/item_flags
#define THICKMATERIAL (1<<0) // Prevents syringes, parapens and hyposprays if equipped to slot_suit or slot_head.
diff --git a/code/datums/observation/turf_enterexit.dm b/code/datums/observation/turf_enterexit.dm
new file mode 100644
index 0000000000..30cec0c39d
--- /dev/null
+++ b/code/datums/observation/turf_enterexit.dm
@@ -0,0 +1,33 @@
+// Observer Pattern Implementation: Turf Entered/Exited
+// Registration type: /turf
+//
+// Raised when: A /turf has a new item in contents, or an item has left it's contents
+//
+// Arguments that the called proc should expect:
+// /turf: The turf that was entered/exited
+// /atom/movable/moving_instance: The instance that entered/exited
+// /atom/old_loc / /atom/new_loc: The previous/new loc of the mover
+
+
+GLOBAL_DATUM_INIT(turf_entered_event, /decl/observ/turf_entered, new)
+GLOBAL_DATUM_INIT(turf_exited_event, /decl/observ/turf_exited, new)
+
+/decl/observ/turf_entered
+ name = "Turf Entered"
+ expected_type = /turf
+
+/decl/observ/turf_exited
+ name = "Turf Exited"
+ expected_type = /turf
+
+/********************
+* Movement Handling *
+********************/
+
+/turf/Entered(var/atom/movable/am, var/atom/old_loc)
+ . = ..()
+ GLOB.turf_entered_event.raise_event(src, am, old_loc)
+
+/turf/Exited(var/atom/movable/am, var/atom/new_loc)
+ . = ..()
+ GLOB.turf_exited_event.raise_event(src, am, new_loc)
\ No newline at end of file
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index 7308083ae6..de7800acfb 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -29,7 +29,6 @@
density = 0
unacidable = 1//Just to be sure.
var/def_zone
- flags = PROXMOVE
pass_flags = PASSTABLE
diff --git a/code/game/atoms.dm b/code/game/atoms.dm
index 123daae654..b1d994d3a3 100644
--- a/code/game/atoms.dm
+++ b/code/game/atoms.dm
@@ -118,15 +118,33 @@
/atom/proc/CheckExit()
return 1
-// If you want to use this, the atom must have the PROXMOVE flag, and the moving
-// atom must also have the PROXMOVE flag currently to help with lag. ~ ComicIronic
-/atom/proc/HasProximity(atom/movable/AM as mob|obj)
+// Used to be for the PROXMOVE flag, but that was terrible, so instead it's just here as a stub for
+// all the atoms that still have the proc, but get events other ways.
+/atom/proc/HasProximity(turf/T, atom/movable/AM, old_loc)
return
+//Register listeners on turfs in a certain range
+/atom/proc/sense_proximity(var/range = 1, var/callback)
+ ASSERT(callback)
+ ASSERT(isturf(loc))
+ var/list/turfs = trange(range, src)
+ for(var/t in turfs)
+ var/turf/T = t
+ GLOB.turf_entered_event.register(T, src, callback)
+
+//Unregister from prox listening in a certain range. You should do this BEFORE you move, but if you
+// really can't, then you can set the center where you moved from.
+/atom/proc/unsense_proximity(var/range = 1, var/callback, var/center)
+ ASSERT(isturf(center) || isturf(loc))
+ var/list/turfs = trange(range, center ? center : src)
+ for(var/t in turfs)
+ var/turf/T = t
+ GLOB.turf_entered_event.unregister(T, src, callback)
+
+
/atom/proc/emp_act(var/severity)
return
-
/atom/proc/bullet_act(obj/item/projectile/P, def_zone)
P.on_hit(src, 0, def_zone)
. = 0
diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm
index 3dbe68fd29..ba5e1038f0 100644
--- a/code/game/machinery/camera/camera.dm
+++ b/code/game/machinery/camera/camera.dm
@@ -87,6 +87,8 @@
// VOREStation Edit End
/obj/machinery/camera/Destroy()
+ if(isMotion())
+ unsense_proximity(callback = .HasProximity)
deactivate(null, 0) //kick anyone viewing out
if(assembly)
qdel(assembly)
diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm
index eac1f89386..ad183a7be8 100644
--- a/code/game/machinery/camera/motion.dm
+++ b/code/game/machinery/camera/motion.dm
@@ -3,15 +3,13 @@
var/detectTime = 0
var/area/ai_monitored/area_motion = null
var/alarm_delay = 100 // Don't forget, there's another 10 seconds in queueAlarm()
- flags = PROXMOVE
/obj/machinery/camera/internal_process()
// motion camera event loop
if (stat & (EMPED|NOPOWER))
return
if(!isMotion())
- . = PROCESS_KILL
- return
+ return PROCESS_KILL
if (detectTime > 0)
var/elapsed = world.time - detectTime
if (elapsed > alarm_delay)
@@ -56,7 +54,7 @@
detectTime = -1
return 1
-/obj/machinery/camera/HasProximity(atom/movable/AM as mob|obj)
+/obj/machinery/camera/HasProximity(turf/T, atom/movable/AM, old_loc)
// Motion cameras outside of an "ai monitored" area will use this to detect stuff.
if (!area_motion)
if(isliving(AM))
diff --git a/code/game/machinery/camera/presets.dm b/code/game/machinery/camera/presets.dm
index d028eedecb..ab5d82b3a5 100644
--- a/code/game/machinery/camera/presets.dm
+++ b/code/game/machinery/camera/presets.dm
@@ -212,9 +212,12 @@ var/global/list/engineering_networks = list(
update_coverage()
/obj/machinery/camera/proc/upgradeMotion()
+ if(!isturf(loc))
+ return //nooooo
assembly.upgrades.Add(new /obj/item/device/assembly/prox_sensor(assembly))
setPowerUsage()
START_MACHINE_PROCESSING(src)
+ sense_proximity(callback = .HasProximity)
update_coverage()
/obj/machinery/camera/proc/setPowerUsage()
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index 572977ceb4..169fc6386c 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -13,7 +13,6 @@
anchored = 1
use_power = USE_POWER_IDLE
idle_power_usage = 2
- flags = PROXMOVE
/obj/machinery/flasher/portable //Portable version of the flasher. Only flashes when anchored
name = "portable flasher"
@@ -92,13 +91,13 @@
flash()
..(severity)
-/obj/machinery/flasher/portable/HasProximity(atom/movable/AM as mob|obj)
- if((disable) || (last_flash && world.time < last_flash + 150))
+/obj/machinery/flasher/portable/HasProximity(turf/T, atom/movable/AM, oldloc)
+ if(disable || !anchored || (last_flash && world.time < last_flash + 150))
return
- if(istype(AM, /mob/living/carbon))
+ if(iscarbon(AM))
var/mob/living/carbon/M = AM
- if((M.m_intent != "walk") && (anchored))
+ if(M.m_intent != "walk")
flash()
/obj/machinery/flasher/portable/attackby(obj/item/weapon/W as obj, mob/user as mob)
@@ -108,11 +107,13 @@
if(!anchored)
user.show_message(text("[src] can now be moved."))
- overlays.Cut()
-
+ cut_overlays()
+ unsense_proximity(callback = .HasProximity)
+
else if(anchored)
user.show_message(text("[src] is now secured."))
- overlays += "[base_state]-s"
+ add_overlay("[base_state]-s")
+ sense_proximity(callback = .HasProximity)
/obj/machinery/button/flasher
name = "flasher button"
diff --git a/code/game/objects/effects/alien/aliens.dm b/code/game/objects/effects/alien/aliens.dm
index 203b768d75..d11b054730 100644
--- a/code/game/objects/effects/alien/aliens.dm
+++ b/code/game/objects/effects/alien/aliens.dm
@@ -441,7 +441,6 @@
var/health = 100
var/status = BURST //can be GROWING, GROWN or BURST; all mutually exclusive
- flags = PROXMOVE
/obj/effect/alien/egg/New()
/*
@@ -545,16 +544,4 @@
/obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 500 + T0C)
health -= 5
- healthcheck()
-/*
-/obj/effect/alien/egg/HasProximity(atom/movable/AM as mob|obj)
- if(status == GROWN)
- if(!CanHug(AM))
- return
-
- var/mob/living/carbon/C = AM
- if(C.stat == CONSCIOUS && C.status_flags & XENO_HOST)
- return
-
- Burst(0)
-*/
\ No newline at end of file
+ healthcheck()
\ No newline at end of file
diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm
index 4169dfc947..406919f96a 100644
--- a/code/game/objects/items/devices/transfer_valve.dm
+++ b/code/game/objects/items/devices/transfer_valve.dm
@@ -9,7 +9,6 @@
var/mob/attacher = null
var/valve_open = 0
var/toggle = 1
- flags = PROXMOVE
/obj/item/device/transfer_valve/attackby(obj/item/item, mob/user)
var/turf/location = get_turf(src) // For admin logs
@@ -57,11 +56,15 @@
return
-/obj/item/device/transfer_valve/HasProximity(atom/movable/AM as mob|obj)
- if(!attached_device) return
- attached_device.HasProximity(AM)
- return
+/obj/item/device/transfer_valve/HasProximity(turf/T, atom/movable/AM, old_loc)
+ attached_device?.HasProximity(T, AM, old_loc)
+/obj/item/device/transfer_valve/Moved(old_loc, direction, forced)
+ . = ..()
+ if(isturf(old_loc))
+ unsense_proximity(callback = .HasProximity, center = old_loc)
+ if(isturf(loc))
+ sense_proximity(callback = .HasProximity)
/obj/item/device/transfer_valve/attack_self(mob/user as mob)
ui_interact(user)
diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm
index a349f3b1fb..0cdf8887a5 100644
--- a/code/game/objects/items/weapons/tanks/tanks.dm
+++ b/code/game/objects/items/weapons/tanks/tanks.dm
@@ -678,6 +678,11 @@ var/list/global/tank_gauge_cache = list()
tank.update_icon()
tank.overlays -= "bomb_assembly"
-/obj/item/device/tankassemblyproxy/HasProximity(atom/movable/AM as mob|obj)
- if(src.assembly)
- src.assembly.HasProximity(AM)
+/obj/item/device/tankassemblyproxy/HasProximity(turf/T, atom/movable/AM, old_loc)
+ assembly?.HasProximity(T, AM, old_loc)
+
+/obj/item/device/tankassemblyproxy/Moved(old_loc, direction, forced)
+ if(isturf(old_loc))
+ unsense_proximity(callback = .HasProximity, center = old_loc)
+ if(isturf(loc))
+ sense_proximity(callback = .HasProximity)
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 8cd5c237cd..1357c71106 100644
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -142,18 +142,8 @@ turf/attackby(obj/item/weapon/W as obj, mob/user as mob)
sleep(2)
O.update_transform()
-var/const/enterloopsanity = 100
-/turf/Entered(atom/atom as mob|obj)
-
- if(movement_disabled)
- to_chat(usr, "Movement is admin-disabled.") //This is to identify lag problems
- return
- ..()
-
- if(!istype(atom, /atom/movable))
- return
-
- var/atom/movable/A = atom
+/turf/Entered(var/atom/movable/A, var/old_loc)
+ . = ..()
if(ismob(A))
var/mob/M = A
@@ -166,16 +156,6 @@ var/const/enterloopsanity = 100
M.inertia_dir = 0
M.make_floating(0)
- var/objects = 0
- if(A && (A.flags & PROXMOVE))
- for(var/atom/movable/thing in range(1))
- if(objects++ > enterloopsanity) break
- spawn(0)
- if(A) //Runtime prevention
- A.HasProximity(thing, 1)
- if ((thing && A) && (thing.flags & PROXMOVE))
- thing.HasProximity(A, 1)
-
/turf/CanPass(atom/movable/mover, turf/target)
if(!target)
return FALSE
diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm
index 2f6d7ab02f..824eb85b0a 100644
--- a/code/modules/assembly/holder.dm
+++ b/code/modules/assembly/holder.dm
@@ -3,7 +3,6 @@
icon = 'icons/obj/assemblies/new_assemblies.dmi'
icon_state = "holder"
item_state = "assembly"
- flags = PROXMOVE
throwforce = 5
w_class = ITEMSIZE_SMALL
throw_speed = 3
@@ -64,11 +63,18 @@
else
. += "\The [src] can be attached!"
-/obj/item/device/assembly_holder/HasProximity(atom/movable/AM as mob|obj)
+/obj/item/device/assembly_holder/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+ if(isturf(old_loc))
+ unsense_proximity(callback = .HasProximity, center = old_loc)
+ if(isturf(loc))
+ sense_proximity(callback = .HasProximity)
+
+/obj/item/device/assembly_holder/HasProximity(turf/T, atom/movable/AM, old_loc)
if(a_left)
- a_left.HasProximity(AM)
+ a_left.HasProximity(T, AM, old_loc)
if(a_right)
- a_right.HasProximity(AM)
+ a_right.HasProximity(T, AM, old_loc)
/obj/item/device/assembly_holder/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm
index c439163fc2..f7d8e3e59e 100644
--- a/code/modules/assembly/proximity.dm
+++ b/code/modules/assembly/proximity.dm
@@ -4,7 +4,6 @@
icon_state = "prox"
origin_tech = list(TECH_MAGNET = 1)
matter = list(DEFAULT_WALL_MATERIAL = 800, "glass" = 200, "waste" = 50)
- flags = PROXMOVE
wires = WIRE_PULSE
secured = 0
@@ -33,7 +32,7 @@
update_icon()
return secured
-/obj/item/device/assembly/prox_sensor/HasProximity(atom/movable/AM as mob|obj)
+/obj/item/device/assembly/prox_sensor/HasProximity(turf/T, atom/movable/AM, old_loc)
if(!istype(AM))
log_debug("DEBUG: HasProximity called with [AM] on [src] ([usr]).")
return
@@ -90,6 +89,10 @@
/obj/item/device/assembly/prox_sensor/Moved(atom/old_loc, direction, forced = FALSE)
. = ..()
+ if(isturf(old_loc))
+ unsense_proximity(range = range, callback = .HasProximity, center = old_loc)
+ if(isturf(loc))
+ sense_proximity(range = range, callback = .HasProximity)
sense()
/obj/item/device/assembly/prox_sensor/interact(mob/user as mob)//TODO: Change this to the wires thingy
diff --git a/code/modules/hydroponics/spreading/spreading.dm b/code/modules/hydroponics/spreading/spreading.dm
index e3ac11ed76..2f93bb108b 100644
--- a/code/modules/hydroponics/spreading/spreading.dm
+++ b/code/modules/hydroponics/spreading/spreading.dm
@@ -72,8 +72,9 @@
var/obj/machinery/portable_atmospherics/hydroponics/soil/invisible/plant
/obj/effect/plant/Destroy()
- if(plant_controller)
- plant_controller.remove_plant(src)
+ if(seed.get_trait(TRAIT_SPREAD)==2)
+ unsense_proximity(callback = .HasProximity, center = get_turf(src))
+ plant_controller.remove_plant(src)
for(var/obj/effect/plant/neighbor in range(1,src))
plant_controller.add_plant(neighbor)
return ..()
@@ -106,6 +107,7 @@
name = seed.display_name
max_health = round(seed.get_trait(TRAIT_ENDURANCE)/2)
if(seed.get_trait(TRAIT_SPREAD)==2)
+ sense_proximity(callback = .HasProximity) // Grabby
max_growth = VINE_GROWTH_STAGES
growth_threshold = max_health/VINE_GROWTH_STAGES
icon = 'icons/obj/hydroponics_vines.dmi'
diff --git a/code/modules/hydroponics/spreading/spreading_response.dm b/code/modules/hydroponics/spreading/spreading_response.dm
index 8c694c8b00..58f4b4da08 100644
--- a/code/modules/hydroponics/spreading/spreading_response.dm
+++ b/code/modules/hydroponics/spreading/spreading_response.dm
@@ -1,4 +1,4 @@
-/obj/effect/plant/HasProximity(var/atom/movable/AM)
+/obj/effect/plant/HasProximity(turf/T, atom/movable/AM, old_loc)
if(!is_mature() || seed.get_trait(TRAIT_SPREAD) != 2)
return
@@ -13,6 +13,14 @@
spawn(1)
entangle(M)
+/obj/effect/plant/Moved(atom/old_loc, direction, forced = FALSE)
+ . = ..()
+ if(seed.get_trait(TRAIT_SPREAD)==2)
+ if(isturf(old_loc))
+ unsense_proximity(callback = .HasProximity, center = old_loc)
+ if(isturf(loc))
+ sense_proximity(callback = .HasProximity)
+
/obj/effect/plant/attack_hand(var/mob/user)
manual_unbuckle(user)
diff --git a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
index ff2f630191..4bfffdfa47 100644
--- a/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
+++ b/code/modules/mob/living/carbon/human/species/xenomorphs/alien_facehugger.dm
@@ -15,7 +15,6 @@ var/const/MAX_ACTIVE_TIME = 400
icon_state = "facehugger"
item_state = "facehugger"
w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
- flags = PROXMOVE
body_parts_covered = FACE|EYES
throw_range = 5
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 375dd0a755..0b516955ef 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -3,7 +3,6 @@
layer = MOB_LAYER
plane = MOB_PLANE
animate_movement = 2
- flags = PROXMOVE
var/datum/mind/mind
var/stat = 0 //Whether a mob is alive or dead. TODO: Move this to living - Nodrak
diff --git a/code/modules/power/singularity/containment_field.dm b/code/modules/power/singularity/containment_field.dm
index 6478ff999a..996847b13b 100644
--- a/code/modules/power/singularity/containment_field.dm
+++ b/code/modules/power/singularity/containment_field.dm
@@ -10,12 +10,15 @@
unacidable = 1
use_power = USE_POWER_OFF
light_range = 4
- flags = PROXMOVE
var/obj/machinery/field_generator/FG1 = null
var/obj/machinery/field_generator/FG2 = null
var/hasShocked = 0 //Used to add a delay between shocks. In some cases this used to crash servers by spawning hundreds of sparks every second.
+/obj/machinery/containment_field/Initialize()
+ sense_proximity(callback = .HasProximity)
+
/obj/machinery/containment_field/Destroy()
+ unsense_proximity(callback = .HasProximity)
if(FG1 && !FG1.clean_up)
FG1.cleanup()
if(FG2 && !FG2.clean_up)
@@ -33,7 +36,7 @@
/obj/machinery/containment_field/ex_act(severity)
return 0
-/obj/machinery/containment_field/HasProximity(atom/movable/AM as mob|obj)
+/obj/machinery/containment_field/HasProximity(turf/T, atom/movable/AM, old_loc)
if(istype(AM,/mob/living/silicon) && prob(40))
shock(AM)
return 1
@@ -42,8 +45,6 @@
return 1
return 0
-
-
/obj/machinery/containment_field/shock(mob/living/user as mob)
if(hasShocked)
return 0
diff --git a/vorestation.dme b/vorestation.dme
index 3dcff27013..0d4628499f 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -355,6 +355,7 @@
#include "code\datums\observation\shuttle_moved.dm"
#include "code\datums\observation\stat_set.dm"
#include "code\datums\observation\turf_changed.dm"
+#include "code\datums\observation\turf_enterexit.dm"
#include "code\datums\observation\unequipped.dm"
#include "code\datums\observation\z_moved.dm"
#include "code\datums\observation\~cleanup.dm"