mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-01-20 22:16:51 +00:00
* Makes turfs persist signals * Splits connect_loc up into two elements, one for stuff that wishes to connect on behalf of something, and one for stuff that just wants to connect normally. Connecting on behalf of someone has a significant amount of overhead, so let's do this to keep things clear * Converts all uses of connect_loc over to the new patterns * Adds some comments, actually makes turfs persist signals * There's no need to detach connect loc anymore, since all it does is unregister signals. Unregisters a signal from formorly decal'd turfs, and makes the changeturf signal persistance stuff actually work * bro fuck documentation * Changes from a var to a proc, prevents admemems and idiots * Extra detail on why we do the copy post qdel
128 lines
3.8 KiB
Plaintext
128 lines
3.8 KiB
Plaintext
/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
|
|
|
|
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)
|