mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 17:52:36 +00:00
* Micro-optimize qdel by only permitting one parameter (#80628) 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. * Micro-optimize qdel by only permitting one parameter --------- Co-authored-by: Mothblocks <35135081+Mothblocks@users.noreply.github.com>
86 lines
3.0 KiB
Plaintext
86 lines
3.0 KiB
Plaintext
/**
|
|
* Component for simplemobs and basicmobs that allow them to carry crates.
|
|
*/
|
|
/datum/component/crate_carrier
|
|
/// The max number of crates we can carry
|
|
var/crate_limit = 3
|
|
/// Typecache of all the types we can pick up and carry
|
|
var/list/carriable_cache
|
|
/// A lazylist of all crates we are carrying
|
|
var/list/atom/movable/crates_in_hand
|
|
|
|
/datum/component/crate_carrier/Initialize(crate_limit = 3, list/carriable_types)
|
|
. = ..()
|
|
if(!isanimal_or_basicmob(parent))
|
|
return COMPONENT_INCOMPATIBLE
|
|
|
|
src.crate_limit = crate_limit
|
|
|
|
if(carriable_types)
|
|
src.carriable_cache = typecacheof(carriable_types)
|
|
|
|
else
|
|
var/static/default_cache = typecacheof(list(/obj/structure/closet/crate))
|
|
src.carriable_cache = default_cache
|
|
|
|
/datum/component/crate_carrier/Destroy(force)
|
|
LAZYCLEARLIST(crates_in_hand)
|
|
return ..()
|
|
|
|
/datum/component/crate_carrier/RegisterWithParent()
|
|
RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(on_examine))
|
|
RegisterSignal(parent, COMSIG_LIVING_UNARMED_ATTACK, PROC_REF(on_unarm_attack))
|
|
RegisterSignal(parent, COMSIG_LIVING_DEATH, PROC_REF(on_death))
|
|
|
|
/datum/component/crate_carrier/UnregisterFromParent()
|
|
UnregisterSignal(parent, list(COMSIG_LIVING_UNARMED_ATTACK, COMSIG_LIVING_DEATH, COMSIG_ATOM_EXAMINE))
|
|
|
|
/// Signal proc for [COMSIG_ATOM_EXAMINE] to show when we're carrying crates
|
|
/datum/component/crate_carrier/proc/on_examine(mob/living/source, mob/examiner, list/examine_list)
|
|
SIGNAL_HANDLER
|
|
|
|
var/num_crates = LAZYLEN(crates_in_hand)
|
|
if(num_crates > 0)
|
|
examine_list += span_notice("[source.p_Theyre()] carrying [num_crates == 1 ? "a crate":"[num_crates] crates"].")
|
|
|
|
/// Signal proc for [COMSIG_LIVING_UNARMED_ATTACK] to allow mobs to pick up or drop crates
|
|
/datum/component/crate_carrier/proc/on_unarm_attack(mob/living/source, atom/target, proximity, modifiers)
|
|
SIGNAL_HANDLER
|
|
|
|
if(source.combat_mode)
|
|
return
|
|
|
|
if(is_type_in_typecache(target, carriable_cache))
|
|
var/atom/movable/movable_target = target
|
|
if(LAZYLEN(crates_in_hand) >= crate_limit)
|
|
source.balloon_alert(source, "too many crates!")
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
for(var/mob/living/inside_mob in movable_target.get_all_contents())
|
|
if(inside_mob.mob_size < MOB_SIZE_HUMAN)
|
|
continue
|
|
source.balloon_alert(source, "crate too heavy!")
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
LAZYADD(crates_in_hand, target)
|
|
movable_target.forceMove(source)
|
|
source.balloon_alert(source, "grabbed crate")
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
if(isopenturf(target) && LAZYLEN(crates_in_hand))
|
|
drop_all_crates(target)
|
|
source.balloon_alert(source, "dropped crate")
|
|
return COMPONENT_CANCEL_ATTACK_CHAIN
|
|
|
|
/// Signal proc for [COMSIG_LIVING_DEATH], so we drop crates on death or gib
|
|
/datum/component/crate_carrier/proc/on_death(mob/living/source, gibbed)
|
|
SIGNAL_HANDLER
|
|
|
|
drop_all_crates(source.drop_location())
|
|
|
|
/// Drops all the crates in our crate list.
|
|
/datum/component/crate_carrier/proc/drop_all_crates(atom/drop_to)
|
|
for(var/obj/structure/closet/crate/held_crate as anything in crates_in_hand)
|
|
held_crate.forceMove(drop_to)
|
|
LAZYREMOVE(crates_in_hand, held_crate)
|