|
|
|
@@ -1,6 +1,53 @@
|
|
|
|
|
/// This element hooks a signal onto the loc the current object is on.
|
|
|
|
|
/// When the object moves, it will unhook the signal and rehook it to the new object.
|
|
|
|
|
/datum/element/connect_loc
|
|
|
|
|
element_flags = ELEMENT_BESPOKE
|
|
|
|
|
id_arg_index = 2
|
|
|
|
|
|
|
|
|
|
/// An assoc list of signal -> procpath to register to the loc this object is on.
|
|
|
|
|
var/list/connections
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/Attach(atom/movable/listener, list/connections)
|
|
|
|
|
. = ..()
|
|
|
|
|
if (!istype(listener))
|
|
|
|
|
return ELEMENT_INCOMPATIBLE
|
|
|
|
|
|
|
|
|
|
src.connections = connections
|
|
|
|
|
|
|
|
|
|
RegisterSignal(listener, COMSIG_MOVABLE_MOVED, .proc/on_moved, override = TRUE)
|
|
|
|
|
update_signals(listener)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/Detach(atom/movable/listener)
|
|
|
|
|
. = ..()
|
|
|
|
|
unregister_signals(listener, listener.loc)
|
|
|
|
|
UnregisterSignal(listener, COMSIG_MOVABLE_MOVED)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/update_signals(atom/movable/listener)
|
|
|
|
|
var/atom/listener_loc = listener.loc
|
|
|
|
|
if(isnull(listener_loc))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
for (var/signal in connections)
|
|
|
|
|
//override=TRUE because more than one connect_loc element instance tracked object can be on the same loc
|
|
|
|
|
listener.RegisterSignal(listener_loc, signal, connections[signal], override=TRUE)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/unregister_signals(datum/listener, atom/old_loc)
|
|
|
|
|
if(isnull(old_loc))
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
for (var/signal in connections)
|
|
|
|
|
listener.UnregisterSignal(old_loc, signal)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/on_moved(atom/movable/listener, atom/old_loc)
|
|
|
|
|
SIGNAL_HANDLER
|
|
|
|
|
unregister_signals(listener, old_loc)
|
|
|
|
|
update_signals(listener)
|
|
|
|
|
|
|
|
|
|
/// This element behaves the same as connect_loc, hooking into a signal on a tracked object's turf
|
|
|
|
|
/// It has the ability to react to that signal on behalf of a seperate listener however
|
|
|
|
|
/// This has great use, primarially for components, but it carries with it some overhead
|
|
|
|
|
/// So we do it seperately rather then intigrating the behavior with the main element
|
|
|
|
|
/datum/element/connect_loc_behalf
|
|
|
|
|
element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH | ELEMENT_COMPLEX_DETACH
|
|
|
|
|
id_arg_index = 3
|
|
|
|
|
|
|
|
|
@@ -10,14 +57,7 @@
|
|
|
|
|
/// An assoc list of locs that are being occupied and a list of targets that occupy them.
|
|
|
|
|
var/list/targets = list()
|
|
|
|
|
|
|
|
|
|
/// The callback used when the turf under the tracked object changes
|
|
|
|
|
var/datum/callback/changeturf_callback
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/New()
|
|
|
|
|
. = ..()
|
|
|
|
|
changeturf_callback = CALLBACK(src, .proc/post_turf_change)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/Attach(datum/listener, atom/movable/tracked, list/connections)
|
|
|
|
|
/datum/element/connect_loc_behalf/Attach(datum/listener, atom/movable/tracked, list/connections)
|
|
|
|
|
. = ..()
|
|
|
|
|
if (!istype(tracked))
|
|
|
|
|
return ELEMENT_INCOMPATIBLE
|
|
|
|
@@ -27,7 +67,7 @@
|
|
|
|
|
RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, .proc/on_moved, override = TRUE)
|
|
|
|
|
update_signals(listener, tracked)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/Detach(datum/listener, atom/movable/tracked, list/connections)
|
|
|
|
|
/datum/element/connect_loc_behalf/Detach(datum/listener, atom/movable/tracked, list/connections)
|
|
|
|
|
. = ..()
|
|
|
|
|
|
|
|
|
|
if(!tracked)
|
|
|
|
@@ -36,7 +76,7 @@
|
|
|
|
|
unregister_signals(listener, tracked, tracked.loc)
|
|
|
|
|
UnregisterSignal(tracked, COMSIG_MOVABLE_MOVED)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/update_signals(datum/listener, atom/movable/tracked)
|
|
|
|
|
/datum/element/connect_loc_behalf/proc/update_signals(datum/listener, atom/movable/tracked)
|
|
|
|
|
var/existing = length(targets[tracked.loc])
|
|
|
|
|
if(!existing)
|
|
|
|
|
targets[tracked.loc] = list()
|
|
|
|
@@ -49,10 +89,7 @@
|
|
|
|
|
listener.RegisterSignal(tracked.loc, signal, connections[signal], override=TRUE)
|
|
|
|
|
//override=TRUE because more than one connect_loc element instance tracked object can be on the same loc
|
|
|
|
|
|
|
|
|
|
if (!existing && isturf(tracked.loc))
|
|
|
|
|
RegisterSignal(tracked.loc, COMSIG_TURF_CHANGE, .proc/on_turf_change)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/unregister_all(datum/listener)
|
|
|
|
|
/datum/element/connect_loc_behalf/proc/unregister_all(datum/listener)
|
|
|
|
|
for(var/atom/location as anything in targets)
|
|
|
|
|
var/list/loc_targets = targets[location]
|
|
|
|
|
for(var/atom/movable/tracked as anything in loc_targets)
|
|
|
|
@@ -64,7 +101,7 @@
|
|
|
|
|
continue
|
|
|
|
|
UnregisterSignal(tracked, COMSIG_MOVABLE_MOVED)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/unregister_signals(datum/listener, atom/movable/tracked, atom/old_loc)
|
|
|
|
|
/datum/element/connect_loc_behalf/proc/unregister_signals(datum/listener, atom/movable/tracked, atom/old_loc)
|
|
|
|
|
if (length(targets[old_loc]) <= 1)
|
|
|
|
|
targets -= old_loc
|
|
|
|
|
else
|
|
|
|
@@ -77,34 +114,9 @@
|
|
|
|
|
for (var/signal in connections)
|
|
|
|
|
listener.UnregisterSignal(old_loc, signal)
|
|
|
|
|
|
|
|
|
|
if (!targets[old_loc] && isturf(old_loc))
|
|
|
|
|
UnregisterSignal(old_loc, COMSIG_TURF_CHANGE)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/on_moved(atom/movable/tracked, atom/old_loc)
|
|
|
|
|
/datum/element/connect_loc_behalf/proc/on_moved(atom/movable/tracked, atom/old_loc)
|
|
|
|
|
SIGNAL_HANDLER
|
|
|
|
|
|
|
|
|
|
var/datum/listener = targets[old_loc][tracked]
|
|
|
|
|
unregister_signals(listener, tracked, old_loc)
|
|
|
|
|
update_signals(listener, tracked)
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/on_turf_change(
|
|
|
|
|
turf/source,
|
|
|
|
|
path,
|
|
|
|
|
new_baseturfs,
|
|
|
|
|
flags,
|
|
|
|
|
list/post_change_callbacks,
|
|
|
|
|
)
|
|
|
|
|
SIGNAL_HANDLER
|
|
|
|
|
|
|
|
|
|
post_change_callbacks += changeturf_callback
|
|
|
|
|
|
|
|
|
|
/datum/element/connect_loc/proc/post_turf_change(turf/new_turf)
|
|
|
|
|
// If we don't cut the targets list before iterating,
|
|
|
|
|
// then we won't re-register the change turf signal.
|
|
|
|
|
var/list/turf_targets = targets[new_turf]
|
|
|
|
|
var/list/targets_copy = turf_targets.Copy()
|
|
|
|
|
turf_targets.Cut()
|
|
|
|
|
|
|
|
|
|
for (var/atom/movable/tracked as anything in targets_copy)
|
|
|
|
|
var/datum/listener = targets_copy[tracked]
|
|
|
|
|
update_signals(listener, tracked)
|
|
|
|
|