mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-11 10:11:09 +00:00
Productionizes #80615. The core optimization is this: ```patch - var/hint = to_delete.Destroy(arglist(args.Copy(2))) // Let our friend know they're about to get fucked up. + var/hint = to_delete.Destroy(force) // Let our friend know they're about to get fucked up. ``` We avoid a heap allocation in the form of copying the args over to a new list. A/B testing shows this results in 33% better overtime, and in a real round shaving off a full second of self time and 0.4 seconds of overtime--both of these would be doubled in the event this is merged as the new proc was only being run 50% of the time.
71 lines
2.0 KiB
Plaintext
71 lines
2.0 KiB
Plaintext
/// Attracts items of a certain typepath
|
|
/datum/component/magnet
|
|
/// Range at which to pull items
|
|
var/pull_range
|
|
/// List of things we attract
|
|
var/list/attracted_typecache
|
|
/// What to do when we pull something
|
|
var/datum/callback/on_pulled
|
|
/// What to do when something reaches us
|
|
var/datum/callback/on_contact
|
|
/// Are we currently working?
|
|
var/active = TRUE
|
|
|
|
/datum/component/magnet/Initialize(
|
|
pull_range = 5,
|
|
attracted_typecache = list(/obj/item/kitchen/spoon, /obj/item/kitchen/fork, /obj/item/knife),
|
|
on_pulled,
|
|
on_contact,
|
|
)
|
|
. = ..()
|
|
if (!length(attracted_typecache))
|
|
CRASH("Attempted to instantiate a [src] on [parent] which does not do anything.")
|
|
if (!isatom(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
src.pull_range = pull_range
|
|
src.attracted_typecache = typecacheof(attracted_typecache)
|
|
src.on_pulled = on_pulled
|
|
src.on_contact = on_contact
|
|
|
|
/datum/component/magnet/RegisterWithParent()
|
|
. = ..()
|
|
START_PROCESSING(SSdcs, src)
|
|
if (!isliving(parent))
|
|
return
|
|
RegisterSignal(parent, COMSIG_MOB_STATCHANGE, PROC_REF(toggle_on_stat_change))
|
|
|
|
/datum/component/magnet/UnregisterFromParent()
|
|
. = ..()
|
|
STOP_PROCESSING(SSdcs, src)
|
|
UnregisterSignal(parent, COMSIG_MOB_STATCHANGE)
|
|
|
|
/datum/component/magnet/Destroy(force)
|
|
STOP_PROCESSING(SSdcs, src)
|
|
on_pulled = null
|
|
on_contact = null
|
|
return ..()
|
|
|
|
/// If a mob dies we stop attracting stuff
|
|
/datum/component/magnet/proc/toggle_on_stat_change(mob/living/source)
|
|
SIGNAL_HANDLER
|
|
if (source.stat == DEAD)
|
|
STOP_PROCESSING(SSdcs, src)
|
|
else
|
|
START_PROCESSING(SSdcs, src)
|
|
|
|
/datum/component/magnet/process(seconds_per_tick)
|
|
for (var/atom/movable/thing in orange(pull_range, parent))
|
|
if (!is_type_in_typecache(thing, attracted_typecache))
|
|
continue
|
|
var/range = get_dist(thing, parent)
|
|
if (range == 0)
|
|
continue
|
|
if (range == 1 && !isnull(on_contact))
|
|
on_contact.Invoke(thing)
|
|
continue
|
|
var/moved = thing.Move(get_step_towards(thing, parent))
|
|
if (moved && !isnull(on_pulled))
|
|
on_pulled.Invoke(thing)
|
|
CHECK_TICK
|