diff --git a/code/datums/ai/monkey/monkey_controller.dm b/code/datums/ai/monkey/monkey_controller.dm index 921a7b93d28..b2c3be20cda 100644 --- a/code/datums/ai/monkey/monkey_controller.dm +++ b/code/datums/ai/monkey/monkey_controller.dm @@ -54,25 +54,25 @@ have ways of interacting with a specific mob and control it. RegisterSignal(new_pawn, COMSIG_MOB_MOVESPEED_UPDATED, .proc/update_movespeed) RegisterSignal(new_pawn, COMSIG_FOOD_EATEN, .proc/on_eat) - AddElement(/datum/element/connect_loc_behalf, new_pawn, loc_connections) + AddComponent(/datum/component/connect_loc_behalf, new_pawn, loc_connections) movement_delay = living_pawn.cached_multiplicative_slowdown return ..() //Run parent at end /datum/ai_controller/monkey/UnpossessPawn(destroy) UnregisterSignal(pawn, list(COMSIG_PARENT_ATTACKBY, COMSIG_ATOM_ATTACK_HAND, COMSIG_ATOM_ATTACK_PAW, COMSIG_ATOM_BULLET_ACT, COMSIG_ATOM_HITBY, COMSIG_LIVING_START_PULL,\ COMSIG_LIVING_TRY_SYRINGE, COMSIG_ATOM_HULK_ATTACK, COMSIG_CARBON_CUFF_ATTEMPTED, COMSIG_MOB_MOVESPEED_UPDATED, COMSIG_ATOM_ATTACK_ANIMAL, COMSIG_MOB_ATTACK_ALIEN)) - RemoveElement(/datum/element/connect_loc_behalf, pawn, loc_connections) + qdel(GetComponent(/datum/component/connect_loc_behalf)) return ..() //Run parent at end // Stops sentient monkeys from being knocked over like weak dunces. /datum/ai_controller/monkey/on_sentience_gained() . = ..() - RemoveElement(/datum/element/connect_loc_behalf, pawn, loc_connections) + qdel(GetComponent(/datum/component/connect_loc_behalf)) /datum/ai_controller/monkey/on_sentience_lost() . = ..() - AddElement(/datum/element/connect_loc_behalf, pawn, loc_connections) + AddComponent(/datum/component/connect_loc_behalf, pawn, loc_connections) /datum/ai_controller/monkey/able_to_run() . = ..() diff --git a/code/datums/components/_component.dm b/code/datums/components/_component.dm index 785b78c4ee9..a0dab5ac16c 100644 --- a/code/datums/components/_component.dm +++ b/code/datums/components/_component.dm @@ -417,7 +417,7 @@ raw_args[1] = src - if(dm != COMPONENT_DUPE_ALLOWED) + if(dm != COMPONENT_DUPE_ALLOWED && dm != COMPONENT_DUPE_SELECTIVE) if(!dt) old_comp = GetExactComponent(nt) else @@ -443,19 +443,19 @@ old_comp.InheritComponent(arglist(arguments)) else old_comp.InheritComponent(new_comp, TRUE) - if(COMPONENT_DUPE_SELECTIVE) - var/list/arguments = raw_args.Copy() - arguments[1] = new_comp - var/make_new_component = TRUE - for(var/datum/component/existing_component as anything in GetComponents(new_type)) - if(existing_component.CheckDupeComponent(arglist(arguments))) - make_new_component = FALSE - QDEL_NULL(new_comp) - break - if(!new_comp && make_new_component) - new_comp = new nt(raw_args) else if(!new_comp) new_comp = new nt(raw_args) // There's a valid dupe mode but there's no old component, act like normal + else if(dm == COMPONENT_DUPE_SELECTIVE) + var/list/arguments = raw_args.Copy() + arguments[1] = new_comp + var/make_new_component = TRUE + for(var/datum/component/existing_component as anything in GetComponents(new_type)) + if(existing_component.CheckDupeComponent(arglist(arguments))) + make_new_component = FALSE + QDEL_NULL(new_comp) + break + if(!new_comp && make_new_component) + new_comp = new nt(raw_args) else if(!new_comp) new_comp = new nt(raw_args) // Dupes are allowed, act like normal diff --git a/code/datums/components/butchering.dm b/code/datums/components/butchering.dm index 147a99ea274..1ac3d15eddf 100644 --- a/code/datums/components/butchering.dm +++ b/code/datums/components/butchering.dm @@ -137,6 +137,7 @@ ///Special snowflake component only used for the recycler. /datum/component/butchering/recycler + /datum/component/butchering/recycler/Initialize(_speed, _effectiveness, _bonus_modifier, _butcher_sound, disabled, _can_be_blunt) if(!istype(parent, /obj/machinery/recycler)) //EWWW return COMPONENT_INCOMPATIBLE @@ -147,7 +148,7 @@ var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = .proc/on_entered, ) - AddElement(/datum/element/connect_loc_behalf, parent, loc_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections) /datum/component/butchering/recycler/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) SIGNAL_HANDLER diff --git a/code/datums/elements/caltrop.dm b/code/datums/components/caltrop.dm similarity index 78% rename from code/datums/elements/caltrop.dm rename to code/datums/components/caltrop.dm index 4b6078f8979..3d4dcb8146c 100644 --- a/code/datums/elements/caltrop.dm +++ b/code/datums/components/caltrop.dm @@ -3,10 +3,7 @@ * * Used for broken glass, cactuses and four sided dice. */ -/datum/element/caltrop - element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH - id_arg_index = 2 - +/datum/component/caltrop ///Minimum damage done when crossed var/min_damage @@ -27,10 +24,11 @@ COMSIG_ATOM_ENTERED = .proc/on_entered, ) -/datum/element/caltrop/Attach(datum/target, min_damage = 0, max_damage = 0, probability = 100, flags = NONE, soundfile = null) + +/datum/component/caltrop/Initialize(min_damage = 0, max_damage = 0, probability = 100, flags = NONE, soundfile = null) . = ..() - if(!isatom(target)) - return ELEMENT_INCOMPATIBLE + if(!isatom(parent)) + return COMPONENT_INCOMPATIBLE src.min_damage = min_damage src.max_damage = max(min_damage, max_damage) @@ -38,12 +36,12 @@ src.flags = flags src.soundfile = soundfile - if(ismovable(target)) - AddElement(/datum/element/connect_loc_behalf, target, crossed_connections) + if(ismovable(parent)) + AddComponent(/datum/component/connect_loc_behalf, parent, crossed_connections) else - RegisterSignal(get_turf(target), COMSIG_ATOM_ENTERED, .proc/on_entered) + RegisterSignal(get_turf(parent), COMSIG_ATOM_ENTERED, .proc/on_entered) -/datum/element/caltrop/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) +/datum/component/caltrop/proc/on_entered(datum/source, atom/movable/arrived, atom/old_loc, list/atom/old_locs) SIGNAL_HANDLER if(!prob(probability)) @@ -106,7 +104,6 @@ return playsound(H, soundfile, 15, TRUE, -3) -/datum/element/caltrop/Detach(datum/target) - . = ..() - if(ismovable(target)) - RemoveElement(/datum/element/connect_loc_behalf, target, crossed_connections) +/datum/component/caltrop/UnregisterFromParent() + if(ismovable(parent)) + qdel(GetComponent(/datum/component/connect_loc_behalf)) diff --git a/code/datums/components/connect_loc_behalf.dm b/code/datums/components/connect_loc_behalf.dm new file mode 100644 index 00000000000..7ab338fe33d --- /dev/null +++ b/code/datums/components/connect_loc_behalf.dm @@ -0,0 +1,81 @@ +/// This component behaves similar to 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 as it needs to hold state which is very likely to lead to bugs if it remains as an element. +/datum/component/connect_loc_behalf + dupe_mode = COMPONENT_DUPE_UNIQUE + + /// An assoc list of signal -> procpath to register to the loc this object is on. + var/list/connections + + var/atom/movable/tracked + + var/atom/tracked_loc + +/datum/component/connect_loc_behalf/Initialize(atom/movable/tracked, list/connections) + . = ..() + if (!istype(tracked)) + return COMPONENT_INCOMPATIBLE + 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) + update_signals() + +/datum/component/connect_loc_behalf/UnregisterFromParent() + unregister_signals() + UnregisterSignal(tracked, list( + COMSIG_MOVABLE_MOVED, + COMSIG_PARENT_QDELETING, + )) + + tracked = null + +/datum/component/connect_loc_behalf/proc/handle_tracked_qdel() + SIGNAL_HANDLER + qdel(src) + +/datum/component/connect_loc_behalf/proc/update_signals() + unregister_signals() + //You may ask yourself, isn't this just silencing an error? + //The answer is yes, but there's no good cheap way to fix it + //What happens is the tracked object or hell the listener gets say, deleted, which makes targets[old_loc] return a null + //The null results in a bad index, because of course it does + //It's not a solvable problem though, since both actions, the destroy and the move, are sourced from the same signal send + //And sending a signal should be agnostic of the order of listeners + //So we need to either pick the order agnositic, or destroy safe + //And I picked destroy safe. Let's hope this is the right path! + if(isnull(tracked.loc)) + return + + tracked_loc = tracked.loc + + for (var/signal in connections) + parent.RegisterSignal(tracked_loc, signal, connections[signal]) + +/datum/component/connect_loc_behalf/proc/unregister_signals() + if(isnull(tracked_loc)) + return + + for (var/signal in connections) + parent.UnregisterSignal(tracked_loc, signal) + + tracked_loc = null + +/datum/component/connect_loc_behalf/proc/on_moved(sigtype, atom/movable/tracked, atom/old_loc) + SIGNAL_HANDLER + update_signals() + diff --git a/code/datums/components/food/edible.dm b/code/datums/components/food/edible.dm index 5d3368aeccc..b9208a6557c 100644 --- a/code/datums/components/food/edible.dm +++ b/code/datums/components/food/edible.dm @@ -45,6 +45,7 @@ Behavior that's still missing from this component that original food items had t ///The type of atom this creates when the object is microwaved. var/atom/microwaved_type + /datum/component/edible/Initialize( list/initial_reagents, food_flags = NONE, @@ -73,7 +74,7 @@ Behavior that's still missing from this component that original food items had t var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = .proc/on_entered, ) - AddElement(/datum/element/connect_loc_behalf, parent, loc_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections) if(isitem(parent)) RegisterSignal(parent, COMSIG_ITEM_ATTACK, .proc/UseFromHand) diff --git a/code/datums/components/infective.dm b/code/datums/components/infective.dm index eab7b3c974a..3656f9eb388 100644 --- a/code/datums/components/infective.dm +++ b/code/datums/components/infective.dm @@ -3,6 +3,7 @@ var/expire_time var/required_clean_types = CLEAN_TYPE_DISEASE + /datum/component/infective/Initialize(list/datum/disease/_diseases, expire_in) if(islist(_diseases)) diseases = _diseases @@ -18,7 +19,7 @@ var/static/list/disease_connections = list( COMSIG_ATOM_ENTERED = .proc/try_infect_crossed, ) - AddElement(/datum/element/connect_loc_behalf, parent, disease_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, disease_connections) RegisterSignal(parent, COMSIG_COMPONENT_CLEAN_ACT, .proc/clean) RegisterSignal(parent, COMSIG_MOVABLE_BUCKLE, .proc/try_infect_buckle) diff --git a/code/datums/components/pellet_cloud.dm b/code/datums/components/pellet_cloud.dm index fea55d23107..15bd6a62111 100644 --- a/code/datums/components/pellet_cloud.dm +++ b/code/datums/components/pellet_cloud.dm @@ -53,6 +53,7 @@ /// for if we're an ammo casing being fired var/mob/living/shooter + /datum/component/pellet_cloud/Initialize(projectile_type=/obj/item/shrapnel, magnitude=5) if(!isammocasing(parent) && !isgrenade(parent) && !islandmine(parent) && !issupplypod(parent) && !ishorrorling(parent)) //SKYRAT EDIT CHANGE: if(!isammocasing(parent) && !isgrenade(parent) && !islandmine(parent) && !issupplypod(parent)) return COMPONENT_INCOMPATIBLE @@ -339,7 +340,7 @@ var/static/list/loc_connections = list( COMSIG_ATOM_EXITED =.proc/grenade_uncrossed, ) - AddElement(/datum/element/connect_loc_behalf, parent, loc_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections) /// Someone dropped the grenade, so set them to the shooter in case they're on top of it when it goes off /datum/component/pellet_cloud/proc/grenade_dropped(obj/item/nade, mob/living/slick_willy) diff --git a/code/datums/components/rot.dm b/code/datums/components/rot.dm index a5545a0caff..c8a2d04e83e 100644 --- a/code/datums/components/rot.dm +++ b/code/datums/components/rot.dm @@ -21,6 +21,8 @@ COMSIG_ATOM_ENTERED = .proc/on_entered, ) + + /datum/component/rot/Initialize(delay, scaling, severity) if(!isatom(parent)) return COMPONENT_INCOMPATIBLE @@ -37,7 +39,7 @@ RegisterSignal(parent, list(COMSIG_ATOM_HULK_ATTACK, COMSIG_ATOM_ATTACK_ANIMAL, COMSIG_ATOM_ATTACK_HAND), .proc/rot_react_touch) RegisterSignal(parent, COMSIG_PARENT_ATTACKBY, .proc/rot_hit_react) if(ismovable(parent)) - AddElement(/datum/element/connect_loc_behalf, parent, loc_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections) RegisterSignal(parent, COMSIG_MOVABLE_BUMP, .proc/rot_react) if(isliving(parent)) RegisterSignal(parent, COMSIG_LIVING_REVIVE, .proc/react_to_revive) //mobs stop this when they come to life @@ -60,7 +62,7 @@ /datum/component/rot/UnregisterFromParent() . = ..() if(ismovable(parent)) - RemoveElement(/datum/element/connect_loc_behalf, parent, loc_connections) + qdel(GetComponent(/datum/component/connect_loc_behalf)) ///One of two procs that modifies blockers, this one handles removing a blocker and potentially restarting the rot /datum/component/rot/proc/start_up(blocker_type) diff --git a/code/datums/components/singularity.dm b/code/datums/components/singularity.dm index b5899b426b6..96fc734b7d8 100644 --- a/code/datums/components/singularity.dm +++ b/code/datums/components/singularity.dm @@ -40,6 +40,8 @@ /// If specified, the singularity will slowly move to this target var/atom/target + + /datum/component/singularity/Initialize( bsa_targetable = TRUE, consume_range = 0, @@ -85,7 +87,7 @@ var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = .proc/on_entered, ) - AddElement(/datum/element/connect_loc_behalf, parent, loc_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections) RegisterSignal(parent, COMSIG_ATOM_BULLET_ACT, .proc/consume_bullets) diff --git a/code/datums/components/slippery.dm b/code/datums/components/slippery.dm index 5c2ca25fe35..d594dff9483 100644 --- a/code/datums/components/slippery.dm +++ b/code/datums/components/slippery.dm @@ -25,6 +25,9 @@ COMSIG_ATOM_ENTERED = .proc/Slip_on_wearer, ) + /// The connect_loc_behalf component for the holder_connections list. + var/datum/weakref/holder_connect_loc_behalf + /datum/component/slippery/Initialize(knockdown, lube_flags = NONE, datum/callback/callback, paralyze, force_drop = FALSE, slot_whitelist) src.knockdown_time = max(knockdown, 0) src.paralyze_time = max(paralyze, 0) @@ -33,15 +36,19 @@ src.callback = callback if(slot_whitelist) src.slot_whitelist = slot_whitelist - if(ismovable(parent)) - AddElement(/datum/element/connect_loc_behalf, parent, default_connections) - if(isitem(parent)) - RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip) - RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop) + add_connect_loc_behalf_to_parent() + if(ismovable(parent)) + if(isitem(parent)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/on_equip) + RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/on_drop) else RegisterSignal(parent, COMSIG_ATOM_ENTERED, .proc/Slip) +/datum/component/slippery/proc/add_connect_loc_behalf_to_parent() + if(ismovable(parent)) + AddComponent(/datum/component/connect_loc_behalf, parent, default_connections) + /datum/component/slippery/InheritComponent(datum/component/slippery/component, i_am_original, knockdown, lube_flags = NONE, datum/callback/callback, paralyze, force_drop = FALSE, slot_whitelist) if(component) knockdown = component.knockdown_time @@ -86,7 +93,8 @@ if((!LAZYLEN(slot_whitelist) || (slot in slot_whitelist)) && isliving(equipper)) holder = equipper - AddElement(/datum/element/connect_loc_behalf, holder, holder_connections) + qdel(GetComponent(/datum/component/connect_loc_behalf)) + AddComponent(/datum/component/connect_loc_behalf, holder, holder_connections) RegisterSignal(holder, COMSIG_PARENT_PREQDELETED, .proc/holder_deleted) /* @@ -113,9 +121,11 @@ SIGNAL_HANDLER UnregisterSignal(user, COMSIG_PARENT_PREQDELETED) - if(holder) - RemoveElement(/datum/element/connect_loc_behalf, holder, holder_connections) - holder = null + + qdel(GetComponent(/datum/component/connect_loc_behalf)) + add_connect_loc_behalf_to_parent() + + holder = null /* * The slip proc, but for equipped items. @@ -132,9 +142,7 @@ /datum/component/slippery/UnregisterFromParent() . = ..() - if(holder) - RemoveElement(/datum/element/connect_loc_behalf, holder, holder_connections) - RemoveElement(/datum/element/connect_loc_behalf, parent, default_connections) + qdel(GetComponent(/datum/component/connect_loc_behalf)) /// Used for making the clown PDA only slip if the clown is wearing his shoes and the elusive banana-skin belt /datum/component/slippery/clowning diff --git a/code/datums/elements/squashable.dm b/code/datums/components/squashable.dm similarity index 94% rename from code/datums/elements/squashable.dm rename to code/datums/components/squashable.dm index 92d0b5e6aa4..ce0e91533e2 100644 --- a/code/datums/elements/squashable.dm +++ b/code/datums/components/squashable.dm @@ -27,7 +27,7 @@ if(!src.on_squash_callback && squash_callback) on_squash_callback = CALLBACK(parent, squash_callback) - AddElement(/datum/element/connect_loc_behalf, parent, loc_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, loc_connections) ///Handles the squashing of the mob /datum/component/squashable/proc/on_entered(turf/source_turf, atom/movable/crossing_movable) @@ -72,4 +72,4 @@ /datum/component/squashable/UnregisterFromParent() . = ..() - RemoveElement(/datum/element/connect_loc_behalf, parent, loc_connections) + qdel(GetComponent(/datum/component/connect_loc_behalf)) diff --git a/code/datums/components/squeak.dm b/code/datums/components/squeak.dm index ce7478d6990..b07e2bd6ff4 100644 --- a/code/datums/components/squeak.dm +++ b/code/datums/components/squeak.dm @@ -26,6 +26,7 @@ COMSIG_ATOM_ENTERED = .proc/play_squeak_crossed, ) + /datum/component/squeak/Initialize(custom_sounds, volume_override, chance_override, step_delay_override, use_delay_override, extrarange, falloff_exponent, fallof_distance) if(!isatom(parent)) return COMPONENT_INCOMPATIBLE @@ -33,7 +34,7 @@ if(ismovable(parent)) RegisterSignal(parent, list(COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_IMPACT, COMSIG_PROJECTILE_BEFORE_FIRE), .proc/play_squeak) - AddElement(/datum/element/connect_loc_behalf, parent, item_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, item_connections) RegisterSignal(parent, COMSIG_MOVABLE_DISPOSING, .proc/disposing_react) if(isitem(parent)) RegisterSignal(parent, list(COMSIG_ITEM_ATTACK, COMSIG_ITEM_ATTACK_OBJ, COMSIG_ITEM_HIT_REACT), .proc/play_squeak) @@ -67,7 +68,7 @@ /datum/component/squeak/UnregisterFromParent() . = ..() - RemoveElement(/datum/element/connect_loc_behalf, parent, item_connections) + qdel(GetComponent(/datum/component/connect_loc_behalf)) /datum/component/squeak/proc/play_squeak() SIGNAL_HANDLER diff --git a/code/datums/components/swarming.dm b/code/datums/components/swarming.dm index 5aa18bd96cf..56493cd9e6a 100644 --- a/code/datums/components/swarming.dm +++ b/code/datums/components/swarming.dm @@ -8,13 +8,14 @@ COMSIG_ATOM_ENTERED = .proc/join_swarm ) + /datum/component/swarming/Initialize(max_x = 24, max_y = 24) if(!ismovable(parent)) return COMPONENT_INCOMPATIBLE offset_x = rand(-max_x, max_x) offset_y = rand(-max_y, max_y) - AddElement(/datum/element/connect_loc_behalf, parent, swarming_loc_connections) + AddComponent(/datum/component/connect_loc_behalf, parent, swarming_loc_connections) /datum/component/swarming/Destroy() for(var/other in swarm_members) diff --git a/code/datums/elements/connect_loc.dm b/code/datums/elements/connect_loc.dm index 4de95339c6e..1687ce35f56 100644 --- a/code/datums/elements/connect_loc.dm +++ b/code/datums/elements/connect_loc.dm @@ -42,94 +42,3 @@ 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 - - /// An assoc list of signal -> procpath to register to the loc this object is on. - var/list/connections - - /// 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_behalf/Attach(datum/listener, atom/movable/tracked, list/connections) - . = ..() - if (!istype(tracked)) - return ELEMENT_INCOMPATIBLE - - src.connections = connections - - RegisterSignal(tracked, COMSIG_MOVABLE_MOVED, .proc/on_moved, override = TRUE) - update_signals(listener, tracked) - -/datum/element/connect_loc_behalf/Detach(datum/listener, atom/movable/tracked, list/connections) - . = ..() - - if(!tracked) - unregister_all(listener) - else if(targets[tracked.loc]) // Detach can happen multiple times due to qdel - unregister_signals(listener, tracked, tracked.loc) - UnregisterSignal(tracked, COMSIG_MOVABLE_MOVED) - -/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() - targets[tracked.loc][tracked] = listener - - if(isnull(tracked.loc)) - return - - for (var/signal in connections) - 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 - -/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) - if(tracked == listener) - unregister_signals(loc_targets[tracked], tracked, location) - else if(loc_targets[tracked] == listener) - unregister_signals(listener, tracked, location) - else - continue - UnregisterSignal(tracked, COMSIG_MOVABLE_MOVED) - -/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 - targets[old_loc] -= tracked - - // Yes this is after the above because we use null as a key when objects are in nullspace - if(isnull(old_loc)) - return - - for (var/signal in connections) - listener.UnregisterSignal(old_loc, signal) - -/datum/element/connect_loc_behalf/proc/on_moved(atom/movable/tracked, atom/old_loc) - SIGNAL_HANDLER - var/list/objects_in_old_loc = targets[old_loc] - //You may ask yourself, isn't this just silencing an error? - //The answer is yes, but there's no good cheap way to fix it - //What happens is the tracked object or hell the listener gets say, deleted, which makes targets[old_loc] return a null - //The null results in a bad index, because of course it does - //It's not a solvable problem though, since both actions, the destroy and the move, are sourced from the same signal send - //And sending a signal should be agnostic of the order of listeners - //So we need to either pick the order agnositic, or destroy safe - //And I picked destroy safe. Let's hope this is the right path! - if(!objects_in_old_loc) - return - var/datum/listener = objects_in_old_loc[tracked] - if(!listener) //See above - return - unregister_signals(listener, tracked, old_loc) - update_signals(listener, tracked) - diff --git a/code/game/objects/effects/decals/cleanable/misc.dm b/code/game/objects/effects/decals/cleanable/misc.dm index e79706459ac..e37c9b9f7f3 100644 --- a/code/game/objects/effects/decals/cleanable/misc.dm +++ b/code/game/objects/effects/decals/cleanable/misc.dm @@ -273,4 +273,4 @@ reagents.add_reagent(/datum/reagent/ants, rand(2, 5)) pixel_x = rand(-5, 5) pixel_y = rand(-5, 5) - AddElement(/datum/element/caltrop, min_damage = 0.2, max_damage = 1, flags = (CALTROP_NOCRAWL | CALTROP_NOSTUN | CALTROP_BYPASS_SHOES), soundfile = 'sound/weapons/bite.ogg') + AddComponent(/datum/component/caltrop, min_damage = 0.2, max_damage = 1, flags = (CALTROP_NOCRAWL | CALTROP_NOSTUN | CALTROP_BYPASS_SHOES), soundfile = 'sound/weapons/bite.ogg') diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 869a3dd7865..d037731e6db 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -89,7 +89,7 @@ /obj/item/dice/d4/Initialize(mapload) . = ..() // 1d4 damage - AddElement(/datum/element/caltrop, min_damage = 1, max_damage = 4) + AddComponent(/datum/component/caltrop, min_damage = 1, max_damage = 4) /obj/item/dice/d6 name = "d6" diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm index 6bd03eab16e..bb495c1bf9d 100644 --- a/code/game/objects/items/stacks/sheets/glass.dm +++ b/code/game/objects/items/stacks/sheets/glass.dm @@ -275,7 +275,7 @@ GLOBAL_LIST_INIT(plastitaniumglass_recipes, list( /obj/item/shard/Initialize() . = ..() - AddElement(/datum/element/caltrop, min_damage = force) + AddComponent(/datum/component/caltrop, min_damage = force) AddComponent(/datum/component/butchering, 150, 65) icon_state = pick("large", "medium", "small") switch(icon_state) diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index 648e1d1d0fd..19c48ed32a5 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -47,11 +47,11 @@ /obj/item/assembly/mousetrap/on_attach() . = ..() - AddElement(/datum/element/connect_loc_behalf, holder, holder_connections) + AddComponent(/datum/component/connect_loc_behalf, holder, holder_connections) /obj/item/assembly/mousetrap/on_detach() . = ..() - RemoveElement(/datum/element/connect_loc_behalf, holder, holder_connections) + qdel(GetComponent(/datum/component/connect_loc_behalf)) /obj/item/assembly/mousetrap/proc/triggered(mob/target, type = "feet") if(!armed) diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm index 81dab89e8da..c06affd2ff6 100644 --- a/code/modules/hydroponics/grown/towercap.dm +++ b/code/modules/hydroponics/grown/towercap.dm @@ -112,7 +112,7 @@ /obj/structure/punji_sticks/Initialize(mapload) . = ..() - AddElement(/datum/element/caltrop, min_damage = 20, max_damage = 30, flags = CALTROP_BYPASS_SHOES) + AddComponent(/datum/component/caltrop, min_damage = 20, max_damage = 30, flags = CALTROP_BYPASS_SHOES) /obj/structure/punji_sticks/spikes name = "wooden spikes" diff --git a/code/modules/mining/lavaland/ash_flora.dm b/code/modules/mining/lavaland/ash_flora.dm index e406600ffe1..3264c0458bf 100644 --- a/code/modules/mining/lavaland/ash_flora.dm +++ b/code/modules/mining/lavaland/ash_flora.dm @@ -144,7 +144,7 @@ /obj/structure/flora/ash/cacti/Initialize(mapload) . = ..() - AddElement(/datum/element/caltrop, min_damage = 3, max_damage = 6, probability = 70) + AddComponent(/datum/component/caltrop, min_damage = 3, max_damage = 6, probability = 70) /obj/structure/flora/ash/seraka icon_state = "seraka_mushroom" diff --git a/code/modules/mob/living/simple_animal/hostile/cockroach.dm b/code/modules/mob/living/simple_animal/hostile/cockroach.dm index f44f9843068..accc44ab76c 100644 --- a/code/modules/mob/living/simple_animal/hostile/cockroach.dm +++ b/code/modules/mob/living/simple_animal/hostile/cockroach.dm @@ -109,7 +109,7 @@ /mob/living/simple_animal/hostile/cockroach/hauberoach/Initialize() . = ..() - AddElement(/datum/element/caltrop, min_damage = 10, max_damage = 15, flags = (CALTROP_BYPASS_SHOES | CALTROP_SILENT)) + AddComponent(/datum/component/caltrop, min_damage = 10, max_damage = 15, flags = (CALTROP_BYPASS_SHOES | CALTROP_SILENT)) /mob/living/simple_animal/hostile/cockroach/hauberoach/make_squashable() AddComponent(/datum/component/squashable, squash_chance = 100, squash_damage = 1, squash_callback = /mob/living/simple_animal/hostile/cockroach/hauberoach/.proc/on_squish) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 7f33abc0429..d15b51c4aa3 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -959,7 +959,7 @@ /obj/item/light/Initialize() . = ..() create_reagents(LIGHT_REAGENT_CAPACITY, INJECTABLE | DRAINABLE) - AddElement(/datum/element/caltrop, min_damage = force) + AddComponent(/datum/component/caltrop, min_damage = force) update() var/static/list/loc_connections = list( COMSIG_ATOM_ENTERED = .proc/on_entered, diff --git a/modular_skyrat/modules/materials_glass/glass.dm b/modular_skyrat/modules/materials_glass/glass.dm index cb6cc62f801..1ce79b4ad51 100644 --- a/modular_skyrat/modules/materials_glass/glass.dm +++ b/modular_skyrat/modules/materials_glass/glass.dm @@ -258,7 +258,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \ /obj/item/shard/Initialize() . = ..() - AddElement(/datum/element/caltrop, min_damage = force) + AddComponent(/datum/component/caltrop, min_damage = force) AddComponent(/datum/component/butchering, 150, 65) icon_state = pick("large", "medium", "small") switch(icon_state) diff --git a/tgstation.dme b/tgstation.dme index e59bcf91e81..fbd22d7f02b 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -548,8 +548,10 @@ #include "code\datums\components\beetlejuice.dm" #include "code\datums\components\bloodysoles.dm" #include "code\datums\components\butchering.dm" +#include "code\datums\components\caltrop.dm" #include "code\datums\components\chasm.dm" #include "code\datums\components\codeword_hearing.dm" +#include "code\datums\components\connect_loc_behalf.dm" #include "code\datums\components\construction.dm" #include "code\datums\components\cracked.dm" #include "code\datums\components\creamed.dm" @@ -617,6 +619,7 @@ #include "code\datums\components\spill.dm" #include "code\datums\components\spinny.dm" #include "code\datums\components\spirit_holding.dm" +#include "code\datums\components\squashable.dm" #include "code\datums\components\squeak.dm" #include "code\datums\components\stationloving.dm" #include "code\datums\components\stationstuck.dm" @@ -740,7 +743,6 @@ #include "code\datums\elements\beauty.dm" #include "code\datums\elements\bed_tucking.dm" #include "code\datums\elements\bsa_blocker.dm" -#include "code\datums\elements\caltrop.dm" #include "code\datums\elements\chewable.dm" #include "code\datums\elements\cleaning.dm" #include "code\datums\elements\climbable.dm" @@ -785,7 +787,6 @@ #include "code\datums\elements\skittish.dm" #include "code\datums\elements\snail_crawl.dm" #include "code\datums\elements\spooky.dm" -#include "code\datums\elements\squashable.dm" #include "code\datums\elements\squish.dm" #include "code\datums\elements\strippable.dm" #include "code\datums\elements\surgery_initiator.dm"