Allows the connect_loc element to have a listener different from the tracked object (#58276)

This commit is contained in:
Emmett Gaines
2021-04-10 18:19:57 -07:00
committed by GitHub
parent f7aebaa133
commit 1c81adac8d
30 changed files with 84 additions and 63 deletions
+3
View File
@@ -16,6 +16,9 @@
* The arguments are the same when the text and number values are the same and all other values have the same ref
*/
#define ELEMENT_BESPOKE (1 << 1)
/// Causes all detach arguments to be passed to detach instead of only being used to identify the element
/// When this is used your Detach proc should have the same signature as your Attach proc
#define ELEMENT_COMPLEX_DETACH (1 << 2)
// How multiple components of the exact same type are handled in the same datum
/// old component is deleted (default)
+6 -2
View File
@@ -26,7 +26,7 @@
RegisterSignal(target, COMSIG_PARENT_QDELETING, .proc/Detach, override = TRUE)
/// Deactivates the functionality defines by the element on the given datum
/datum/element/proc/Detach(datum/source, force)
/datum/element/proc/Detach(datum/source, ...)
SIGNAL_HANDLER
SEND_SIGNAL(source, COMSIG_ELEMENT_DETACH, src)
@@ -54,4 +54,8 @@
*/
/datum/proc/_RemoveElement(list/arguments)
var/datum/element/ele = SSdcs.GetElement(arguments)
ele.Detach(src)
if(ele.element_flags & ELEMENT_COMPLEX_DETACH)
arguments[1] = src
ele.Detach(arglist(arguments))
else
ele.Detach(src)
+1 -1
View File
@@ -14,7 +14,7 @@
RegisterSignal(to_track, COMSIG_MOVABLE_MOVED, .proc/handle_move)
return ..()
/datum/element/atmos_sensitive/Detach(datum/source, force)
/datum/element/atmos_sensitive/Detach(datum/source)
var/atom/us = source
us.UnregisterSignal(get_turf(us), COMSIG_TURF_EXPOSE)
if(us.flags_1 & ATMOS_IS_PROCESSING_1)
+1 -1
View File
@@ -29,7 +29,7 @@
else
RegisterSignal(target, COMSIG_GUN_FIRED, .proc/gun_fired)
/datum/element/backblast/Detach(datum/source, force)
/datum/element/backblast/Detach(datum/source)
if(source)
UnregisterSignal(source, COMSIG_GUN_FIRED)
return ..()
+1 -1
View File
@@ -49,7 +49,7 @@
old_area.totalbeauty -= beauty * beauty_counter[source]
old_area.update_beauty()
/datum/element/beauty/Detach(datum/source, force)
/datum/element/beauty/Detach(datum/source)
if(!beauty_counter[source])
return ..()
var/area/current_area = get_area(source)
+1 -1
View File
@@ -23,7 +23,7 @@
RegisterSignal(target, COMSIG_MOUSEDROPPED_ONTO, .proc/mousedrop_receive)
RegisterSignal(target, COMSIG_ATOM_BUMPED, .proc/try_speedrun)
/datum/element/climbable/Detach(datum/target, force)
/datum/element/climbable/Detach(datum/target)
UnregisterSignal(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_PARENT_EXAMINE, COMSIG_MOUSEDROPPED_ONTO, COMSIG_ATOM_BUMPED))
return ..()
+47 -33
View File
@@ -1,8 +1,8 @@
/// 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 | ELEMENT_DETACH
id_arg_index = 2
element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH | ELEMENT_COMPLEX_DETACH
id_arg_index = 3
/// An assoc list of signal -> procpath to register to the loc this object is on.
var/list/connections
@@ -10,56 +10,71 @@
/// An assoc list of locs that are being occupied and a list of targets that occupy them.
var/list/targets = list()
/datum/element/connect_loc/Attach(datum/target, list/connections)
/// The callback used when the turf under the tracked object changes
var/datum/callback/changeturf_callback
/datum/element/connect_loc/New()
. = ..()
if (!ismovable(target))
changeturf_callback = CALLBACK(src, .proc/post_turf_change)
/datum/element/connect_loc/Attach(datum/listener, atom/movable/tracked, list/connections)
. = ..()
if (!istype(tracked))
return ELEMENT_INCOMPATIBLE
src.connections = connections
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/on_moved)
update_signals(target)
/datum/element/connect_loc/Detach(datum/source, force)
RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, .proc/on_moved)
update_signals(listener, tracked)
/datum/element/connect_loc/Detach(datum/listener, atom/movable/tracked, list/connections)
. = ..()
if (!ismovable(source))
if(!tracked)
tracked = listener
if(!istype(tracked))
return
var/atom/movable/movable_source = source
if (!isnull(tracked.loc))
unregister_signals(listener, tracked, tracked.loc)
if (!isnull(movable_source.loc))
unregister_signals(source, movable_source.loc)
UnregisterSignal(tracked, COMSIG_MOVABLE_MOVED)
/datum/element/connect_loc/proc/update_signals(atom/movable/target)
if (isnull(target.loc))
/datum/element/connect_loc/proc/update_signals(datum/listener, atom/movable/tracked)
var/existing = length(targets[tracked.loc])
LAZYSET(targets[tracked.loc], tracked, listener)
if (isnull(tracked.loc))
return
LAZYSET(targets[target.loc], target, TRUE)
for (var/signal in connections)
target.RegisterSignal(target.loc, signal, connections[signal])
listener.RegisterSignal(tracked.loc, signal, connections[signal])
if (isturf(target.loc) && length(targets[target.loc]) == 1)
RegisterSignal(target.loc, COMSIG_TURF_CHANGE, .proc/on_turf_change)
if (!existing && isturf(tracked.loc))
RegisterSignal(tracked.loc, COMSIG_TURF_CHANGE, .proc/on_turf_change)
/datum/element/connect_loc/proc/unregister_signals(atom/movable/target, atom/old_loc)
targets[old_loc] -= target
/datum/element/connect_loc/proc/unregister_signals(datum/listener, atom/movable/tracked, atom/old_loc)
targets[old_loc] -= tracked
if (length(targets[old_loc]) == 0)
targets -= old_loc
for (var/signal in connections)
target.UnregisterSignal(old_loc, signal)
// Yes this is after the above because we use null as a key when objects are in nullspace
if(isnull(old_loc))
return
if (isturf(old_loc) && !(target.loc in targets))
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/source, atom/old_loc)
/datum/element/connect_loc/proc/on_moved(atom/movable/tracked, atom/old_loc)
SIGNAL_HANDLER
if (!isnull(old_loc))
unregister_signals(source, old_loc)
update_signals(source)
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,
@@ -70,10 +85,9 @@
)
SIGNAL_HANDLER
post_change_callbacks += CALLBACK(src, .proc/post_turf_change)
post_change_callbacks += changeturf_callback
/datum/element/connect_loc/proc/post_turf_change(turf/new_turf)
SHOULD_NOT_SLEEP(TRUE)
for (var/atom/movable/target as anything in targets[new_turf])
update_signals(target)
for (var/atom/movable/tracked as anything in targets[new_turf])
var/datum/listener = targets[new_turf][tracked]
update_signals(listener, tracked)
+1 -1
View File
@@ -92,7 +92,7 @@
pic.alpha = _alpha
return TRUE
/datum/element/decal/Detach(atom/source, force)
/datum/element/decal/Detach(atom/source)
UnregisterSignal(source, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_PARENT_EXAMINE, COMSIG_ATOM_UPDATE_OVERLAYS, COMSIG_TURF_ON_SHUTTLE_MOVE))
source.update_appearance()
if(isitem(source))
+1 -1
View File
@@ -8,7 +8,7 @@
RegisterSignal(target, COMSIG_ATOM_GET_EXAMINE_NAME, .proc/get_examine_name, TRUE)
/datum/element/decal/blood/Detach(atom/source, force)
/datum/element/decal/blood/Detach(atom/source)
UnregisterSignal(source, COMSIG_ATOM_GET_EXAMINE_NAME)
return ..()
+1 -1
View File
@@ -12,7 +12,7 @@
RegisterSignal(target, COMSIG_MOUSEDROP_ONTO, .proc/pick_up)
return ..()
/datum/element/drag_pickup/Detach(datum/source, force)
/datum/element/drag_pickup/Detach(datum/source)
UnregisterSignal(source, COMSIG_MOUSEDROP_ONTO)
return ..()
+1 -1
View File
@@ -20,7 +20,7 @@
RegisterSignal(target, COMSIG_ITEM_ATTACK, .proc/item_attack, override = TRUE)
RegisterSignal(target, COMSIG_ITEM_ATTACK_SELF, .proc/item_attack_self, override = TRUE)
/datum/element/firestacker/Detach(datum/source, force)
/datum/element/firestacker/Detach(datum/source)
. = ..()
UnregisterSignal(source, list(COMSIG_MOVABLE_IMPACT, COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_SELF))
+1 -1
View File
@@ -16,7 +16,7 @@
if(isturf(target))
RegisterSignal(target, COMSIG_TURF_HAS_GRAVITY, .proc/turf_gravity_check)
/datum/element/forced_gravity/Detach(datum/source, force)
/datum/element/forced_gravity/Detach(datum/source)
. = ..()
var/static/list/signals_b_gone = list(COMSIG_ATOM_HAS_GRAVITY, COMSIG_TURF_HAS_GRAVITY)
UnregisterSignal(source, signals_b_gone)
+1 -1
View File
@@ -13,7 +13,7 @@
master.AddElement(/datum/element/movetype_handler)
ADD_TRAIT(master, TRAIT_MOVE_FLYING, ELEMENT_TRAIT)
/datum/element/haunted/Detach(datum/source, force)
/datum/element/haunted/Detach(datum/source)
. = ..()
var/atom/movable/master = source
master.remove_filter("haunt_glow")
+1 -1
View File
@@ -24,7 +24,7 @@
target.set_light_range(0)
target.set_light_on(FALSE)
/datum/element/light_eaten/Detach(datum/source, force)
/datum/element/light_eaten/Detach(datum/source)
UnregisterSignal(source, list(
COMSIG_ATOM_SET_LIGHT_POWER,
COMSIG_ATOM_SET_LIGHT_RANGE,
+1 -1
View File
@@ -22,7 +22,7 @@
return ..()
/datum/element/light_eater/Detach(datum/source, force)
/datum/element/light_eater/Detach(datum/source)
UnregisterSignal(source, list(
COMSIG_MOVABLE_IMPACT,
COMSIG_ITEM_AFTERATTACK,
+1 -1
View File
@@ -31,7 +31,7 @@
if(isvehicle(target))
RegisterSignal(target, COMSIG_PARENT_ATTACKBY, .proc/check_potion)
/datum/element/ridable/Detach(datum/target, force)
/datum/element/ridable/Detach(datum/target)
UnregisterSignal(target, list(COMSIG_MOVABLE_PREBUCKLE, COMSIG_PARENT_ATTACKBY))
return ..()
+1 -1
View File
@@ -20,7 +20,7 @@ clamping the Knockback_Force value below. */
override_throw_val = throw_amount
override_speed_val = speed_amount
/datum/element/selfknockback/Detach(datum/source, force)
/datum/element/selfknockback/Detach(datum/source)
. = ..()
UnregisterSignal(source, list(COMSIG_ITEM_AFTERATTACK, COMSIG_PROJECTILE_FIRE))
+1 -1
View File
@@ -24,7 +24,7 @@
src.items = items
src.should_strip_proc_path = should_strip_proc_path
/datum/element/strippable/Detach(datum/source, force)
/datum/element/strippable/Detach(datum/source)
. = ..()
UnregisterSignal(source, COMSIG_MOUSEDROP_ONTO)
+1 -1
View File
@@ -29,7 +29,7 @@ This element is used in vat growing to allow for the object to be
src.virus_chance = virus_chance
///Stops listening to the swab signal; you can no longer be swabbed.
/datum/element/swabable/Detach(datum/source, force)
/datum/element/swabable/Detach(datum/source)
. = ..()
if(!isatom(source) || isarea(source))
return ELEMENT_INCOMPATIBLE
+1 -1
View File
@@ -19,7 +19,7 @@
RegisterSignal(target, COMSIG_TOOL_IN_USE, .proc/prob_flash)
RegisterSignal(target, COMSIG_TOOL_START_USE, .proc/flash)
/datum/element/tool_flash/Detach(datum/source, force)
/datum/element/tool_flash/Detach(datum/source)
. = ..()
UnregisterSignal(source, list(COMSIG_TOOL_IN_USE, COMSIG_TOOL_START_USE))
+1 -1
View File
@@ -22,7 +22,7 @@
update_multiz(our_turf, TRUE, TRUE)
/datum/element/turf_z_transparency/Detach(datum/source, force)
/datum/element/turf_z_transparency/Detach(datum/source)
. = ..()
var/turf/our_turf = source
our_turf.vis_contents.len = 0
+1 -1
View File
@@ -9,7 +9,7 @@
else
RegisterSignal(target, COMSIG_MOVABLE_MOVED, .proc/Waddle)
/datum/element/waddling/Detach(datum/source, force)
/datum/element/waddling/Detach(datum/source)
. = ..()
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
+2 -2
View File
@@ -181,7 +181,7 @@
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
UnregisterSignal(user, COMSIG_LIVING_SET_BODY_POSITION)
UnregisterSignal(user, COMSIG_PARENT_QDELETING)
/obj/machinery/door/firedoor/attack_ai(mob/user)
add_fingerprint(user)
if(welded || operating || machine_stat & NOPOWER)
@@ -273,7 +273,7 @@
COMSIG_ATOM_EXIT = .proc/on_exit,
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/connect_loc, src, loc_connections)
/obj/machinery/door/firedoor/border_only/CanAllowThrough(atom/movable/mover, turf/target)
. = ..()
+1 -1
View File
@@ -46,7 +46,7 @@
COMSIG_ATOM_EXIT = .proc/on_exit,
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/connect_loc, src, loc_connections)
/obj/machinery/door/window/ComponentInitialize()
. = ..()
+1 -1
View File
@@ -84,7 +84,7 @@
COMSIG_ATOM_EXIT = .proc/on_exit,
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/connect_loc, src, loc_connections)
/obj/structure/railing/proc/on_exit(datum/source, atom/movable/leaving, atom/new_location)
SIGNAL_HANDLER
+1 -1
View File
@@ -38,7 +38,7 @@
COMSIG_ATOM_EXIT = .proc/on_exit,
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/connect_loc, src, loc_connections)
return ..()
@@ -39,7 +39,7 @@
COMSIG_ATOM_EXIT = .proc/on_exit,
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/connect_loc, src, loc_connections)
/obj/structure/windoor_assembly/Destroy()
density = FALSE
+1 -1
View File
@@ -73,7 +73,7 @@
)
if (flags_1 & ON_BORDER_1)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/connect_loc, src, loc_connections)
/obj/structure/window/ComponentInitialize()
. = ..()
@@ -50,7 +50,7 @@
COMSIG_ATOM_EXIT = .proc/on_exit,
)
AddElement(/datum/element/connect_loc, loc_connections)
AddElement(/datum/element/connect_loc, src, loc_connections)
/obj/structure/necropolis_gate/Destroy(force)
if(force)
+1 -1
View File
@@ -63,7 +63,7 @@
COMSIG_MOCK_SIGNAL = .proc/on_receive_mock_signal,
)
AddElement(/datum/element/connect_loc, connections)
AddElement(/datum/element/connect_loc, src, connections)
/obj/item/watches_mock_calls/proc/on_receive_mock_signal(datum/source)
SIGNAL_HANDLER