Make stack merging much less of a potential lagfest (#91015)

This commit is contained in:
Lucy
2025-05-15 16:14:08 -04:00
committed by Roxy
parent f74b7b01d5
commit aecb32c4b4
+39 -24
View File
@@ -83,6 +83,9 @@
. = ..()
if(merge)
. = INITIALIZE_HINT_LATELOAD
var/materials_mult = amount
if(LAZYLEN(mat_override))
materials_mult *= mat_amt
@@ -90,15 +93,6 @@
if(LAZYLEN(mats_per_unit))
initialize_materials(mats_per_unit, materials_mult)
if(merge)
for(var/obj/item/stack/item_stack in loc)
if(item_stack == src)
continue
if(can_merge(item_stack))
INVOKE_ASYNC(src, PROC_REF(merge_without_del), item_stack)
if(is_zero_amount(delete_if_zero = FALSE))
return INITIALIZE_HINT_QDEL
recipes = get_main_recipes().Copy()
if(material_type)
var/datum/material/what_are_we_made_of = GET_MATERIAL_REF(material_type) //First/main material
@@ -111,19 +105,51 @@
update_weight()
update_appearance()
var/static/list/loc_connections = list(
COMSIG_ATOM_ENTERED = PROC_REF(on_movable_entered_occupied_turf),
)
AddElement(/datum/element/connect_loc, loc_connections)
if(is_path_in_list(merge_type, GLOB.golem_stack_food_directory))
AddComponent(/datum/component/golem_food, golem_food_key = merge_type)
/obj/item/stack/LateInitialize()
merge_with_loc()
/obj/item/stack/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change)
. = ..()
if((!throwing || throwing.target_turf == loc) && old_loc != loc && (flags_1 & INITIALIZED_1))
merge_with_loc()
///Called to lazily update the materials of the item whenever the used or if more is added
/obj/item/stack/proc/update_custom_materials()
if(length(mats_per_unit))
set_custom_materials(mats_per_unit, amount)
/obj/item/stack/proc/find_other_stack(list/already_found)
if(QDELETED(src) || isnull(loc))
return
for(var/obj/item/stack/item_stack in loc)
if(item_stack == src || QDELING(item_stack) || (item_stack.amount >= item_stack.max_amount))
continue
if(!(item_stack.flags_1 & INITIALIZED_1))
stack_trace("find_other_stack found uninitialized stack in loc? skipping for now")
continue
var/stack_ref = REF(item_stack)
if(already_found[stack_ref])
continue
if(can_merge(item_stack))
already_found[stack_ref] = TRUE
return item_stack
/// Tries to merge the stack with everything on the same tile.
/obj/item/stack/proc/merge_with_loc()
var/list/already_found = list() // change to alist whenever dreamchecker and such finally supports that
var/obj/item/other_stack = find_other_stack(already_found)
var/sanity = max_amount // just in case
while(other_stack && sanity > 0)
sanity--
if(merge(other_stack))
return FALSE
other_stack = find_other_stack(already_found)
return TRUE
/obj/item/stack/apply_material_effects(list/materials)
. = ..()
if(amount)
@@ -662,17 +688,6 @@
. = merge_without_del(target_stack, limit)
is_zero_amount(delete_if_zero = TRUE)
/// Signal handler for connect_loc element. Called when a movable enters the turf we're currently occupying. Merges if possible.
/obj/item/stack/proc/on_movable_entered_occupied_turf(datum/source, atom/movable/arrived)
SIGNAL_HANDLER
// Edge case. This signal will also be sent when src has entered the turf. Don't want to merge with ourselves.
if(arrived == src)
return
if(!arrived.throwing && can_merge(arrived))
INVOKE_ASYNC(src, PROC_REF(merge), arrived)
/obj/item/stack/hitby(atom/movable/hitting, skipcatch, hitpush, blocked, datum/thrownthing/throwingdatum)
if(can_merge(hitting, inhand = TRUE))
merge(hitting)