diff --git a/code/datums/storage/subtypes/rped.dm b/code/datums/storage/subtypes/rped.dm index a8edde8a693..390cd17f976 100644 --- a/code/datums/storage/subtypes/rped.dm +++ b/code/datums/storage/subtypes/rped.dm @@ -34,6 +34,11 @@ /obj/item/stack/sheet/bluespace_crystal, ) +/datum/storage/rped/New(atom/parent, max_slots, max_specific_storage, max_total_storage, numerical_stacking, allow_quick_gather, allow_quick_empty, collection_mode, attack_hand_interact) + . = ..() + var/atom/resolve_parent = src.parent?.resolve() + RegisterSignal(resolve_parent, COMSIG_ITEM_ATTACK_SELF, PROC_REF(rped_mass_empty), TRUE) + /datum/storage/rped/can_insert(obj/item/to_insert, mob/user, messages = TRUE, force = FALSE) . = ..() @@ -77,4 +82,46 @@ return . +/// overridden mass_empty, so as to dump only the lowest tier of parts currently in the RPED +/datum/storage/rped/proc/rped_mass_empty(datum/source, atom/location, force) + SIGNAL_HANDLER + + if(!allow_quick_empty && !force) + return + + remove_lowest_tier(get_turf(location)) + +/** + * Searches through everything currently in storage, calculates the lowest tier of parts inside of it, + * and then dumps out every part that has the equal tier of parts. Likely a worse implementation of remove_all. + * + * @param atom/target where we're placing the item + */ +/datum/storage/rped/proc/remove_lowest_tier(atom/target) // look whatever happens here i'm not proud of this. at all. + var/obj/item/resolve_parent = parent?.resolve() + var/obj/item/resolve_location = real_location?.resolve() + var/list/obj/item/parts_list = list() + var/current_lowest_tier = INFINITY + if(!resolve_parent || !resolve_location) + return + + if(!target) + target = get_turf(resolve_parent) + + for(var/obj/item/thing in resolve_location) + if(thing.loc != resolve_location) + continue + parts_list.Add(thing) + if(parts_list.len > 0) + parts_list = reverse_range(sortTim(parts_list, GLOBAL_PROC_REF(cmp_rped_sort))) + current_lowest_tier = parts_list[1].get_part_rating() + resolve_parent.balloon_alert(resolve_parent.loc, "dropping lowest rated parts...") + for(var/obj/item/part in parts_list) + if(part.get_part_rating() != current_lowest_tier) + break + if(!attempt_remove(part, target, silent = TRUE)) + continue + part.pixel_x = part.base_pixel_x + rand(-8, 8) + part.pixel_y = part.base_pixel_y + rand(-8, 8) + #undef MAX_STACK_PICKUP diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm index 5e57fecd4e0..7fcaa015f91 100644 --- a/code/modules/research/stock_parts.dm +++ b/code/modules/research/stock_parts.dm @@ -225,14 +225,11 @@ If you create T5+ please take a pass at mech_fabricator.dm. The parts being good part_list = sortTim(part_list, GLOBAL_PROC_REF(cmp_rped_sort)) return part_list -/proc/cmp_rped_sort(obj/item/A, obj/item/B) +/proc/cmp_rped_sort(obj/item/first_item, obj/item/second_item) /** - * stacks components like cable,glass,plasteel are not component parts hence their get_part_rating() method is undefined and would return undefined values causing errors - * so we assign them an default rating of 1 when the RPED sorts these components + * even though stacks aren't stock parts, get_part_rating() is defined on the item level (see /obj/item/proc/get_part_rating()) and defaults to returning 0. */ - var/a_rating = isstack(A) ? 1 : A.get_part_rating() - var/b_rating = isstack(B) ? 1 : B.get_part_rating() - return b_rating - a_rating + return second_item.get_part_rating() - first_item.get_part_rating() /obj/item/stock_parts name = "stock part"