Files
Bubberstation/code/datums/elements/give_turf_traits.dm
SkyratBot 606f0009a1 [MIRROR] Removes two redundant components [MDB IGNORE] (#22613)
* Removes two redundant components (#76866)

## About The Pull Request

We're starting to get to have enough components that people don't
realise that what they want already exists but doesn't have the name
they expect 🙃

I recently added `track_hierarchical_movement` which is similar enough
to `connect_containers` that it shouldn't independently exist, even if I
like sending a new signal more than the ugly setup pattern for
`connect_loc`.

`trait_loc` is actually older than `give_turf_traits` but
`give_turf_traits` covers more edge cases than `turf_loc` so seems like
the better one to maintain.
HOWEVER `give_turf_traits` held a list of references to atoms in it,
which isn't great in an element. I couldn't think of a way to completely
eliminate the list, but it isn't a list of references any more so it
shouldn't cause any hard deletions.

## Why It's Good For The Game

Having two components which do the same thing but marginally differently
is confusing and going to cause us trouble down the line.

## Changelog

Not player facing

* Removes two redundant components

---------

Co-authored-by: Jacquerel <hnevard@gmail.com>
2023-07-21 13:27:45 -04:00

80 lines
3.2 KiB
Plaintext

/// A bespoke element that adds a set of traits to the turf while occupied by at least one attached movabled.
/datum/element/give_turf_traits
element_flags = ELEMENT_DETACH_ON_HOST_DESTROY|ELEMENT_BESPOKE
argument_hash_start_idx = 2
///A list of traits that are added to the turf while occupied.
var/list/traits
///List of sources we are using to reapply traits when turf changes
var/list/trait_sources = list()
/datum/element/give_turf_traits/Attach(atom/movable/target, list/traits)
. = ..()
if(!istype(target))
return ELEMENT_INCOMPATIBLE
src.traits = traits
RegisterSignal(target, COMSIG_MOVABLE_MOVED, PROC_REF(on_moved))
if(isturf(target.loc))
add_to_occupied_turfs(target.loc, target)
/datum/element/give_turf_traits/Detach(atom/movable/source)
UnregisterSignal(source, COMSIG_MOVABLE_MOVED)
if(isturf(source.loc))
remove_from_occupied_turfs(source.loc, source)
return ..()
/// Removes the trait from the old turf and adds it to the new one.
/datum/element/give_turf_traits/proc/on_moved(atom/movable/source, atom/old_loc)
SIGNAL_HANDLER
if(isturf(old_loc))
remove_from_occupied_turfs(old_loc, source)
if(isturf(source.loc))
add_to_occupied_turfs(source.loc, source)
/**
* Registers the turf signals if it was previously unoccupied and adds it to the list of occupied turfs.
* Otherwise, it just adds the movable to the assoc value of lists occupying the turf.
*/
/datum/element/give_turf_traits/proc/add_to_occupied_turfs(turf/location, atom/movable/source)
var/trait_source = REF(source)
if(isnull(trait_sources) || isnull(trait_sources[location]))
RegisterSignal(location, COMSIG_TURF_CHANGE, PROC_REF(pre_change_turf))
LAZYADDASSOCLIST(trait_sources, location, trait_source)
var/update_movespeeds = (TRAIT_TURF_IGNORE_SLOWDOWN in traits) && !HAS_TRAIT(location, TRAIT_TURF_IGNORE_SLOWDOWN)
for(var/trait in traits)
ADD_TRAIT(location, trait, trait_source)
if(update_movespeeds)
for(var/mob/living/living in location)
living.update_turf_movespeed()
/**
* Unregisters the turf signals if it's no longer unoccupied and removes it from the list of occupied turfs.
* Otherwise, it just removes the movable from the assoc value of lists occupying the turf.
*/
/datum/element/give_turf_traits/proc/remove_from_occupied_turfs(turf/location, atom/movable/source)
var/trait_source = REF(source)
LAZYREMOVEASSOC(trait_sources, location, trait_source)
if(isnull(trait_sources) || isnull(trait_sources[location]))
UnregisterSignal(location, COMSIG_TURF_CHANGE)
for(var/trait in traits)
REMOVE_TRAIT(location, trait, trait_source)
if((TRAIT_TURF_IGNORE_SLOWDOWN in traits) && !HAS_TRAIT(location, TRAIT_TURF_IGNORE_SLOWDOWN))
for(var/mob/living/living in location)
living.update_turf_movespeed()
/// Signals and components are carried over when the turf is changed, so they've to be readded post-change.
/datum/element/give_turf_traits/proc/pre_change_turf(turf/changed, path, list/new_baseturfs, flags, list/post_change_callbacks)
SIGNAL_HANDLER
post_change_callbacks += CALLBACK(src, PROC_REF(reoccupy_turf))
/// Reapply turf traits to the provided turf
/datum/element/give_turf_traits/proc/reoccupy_turf(turf/changed)
for(var/trait in traits)
for(var/source in trait_sources[changed])
ADD_TRAIT(changed, trait, source)