From 6693a1257244fa1989db890118a9b19ab69cccbd Mon Sep 17 00:00:00 2001 From: NovaBot <154629622+NovaBot13@users.noreply.github.com> Date: Thu, 8 Feb 2024 18:00:40 -0500 Subject: [PATCH] [MIRROR] Comprehensive cleanup of storage datum, replaces the weakrefs with just refs (because they were managed already) (#785) * Comprehensive cleanup of storage datum, replaces the weakrefs with just refs (because they were managed already) * CI fix * Clean up modular items * Surgery Tray Fix --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Co-authored-by: SomeRandomOwl <2568378+SomeRandomOwl@users.noreply.github.com> --- code/__DEFINES/dcs/signals/signals_object.dm | 4 +- code/__HELPERS/atoms.dm | 10 - code/datums/storage/storage.dm | 801 ++++++++---------- .../datums/storage/subtypes/bag_of_holding.dm | 43 +- code/datums/storage/subtypes/cards.dm | 89 +- code/datums/storage/subtypes/duffel_bag.dm | 7 +- .../storage/subtypes/extract_inventory.dm | 27 +- code/datums/storage/subtypes/fish_case.dm | 57 +- code/datums/storage/subtypes/implant.dm | 9 +- code/datums/storage/subtypes/pockets.dm | 129 ++- code/datums/storage/subtypes/rped.dm | 44 +- code/datums/storage/subtypes/surgery_tray.dm | 8 +- code/datums/storage/subtypes/trash.dm | 17 +- code/game/atom/atom_storage.dm | 18 +- code/game/objects/items.dm | 3 +- code/game/objects/items/crayons.dm | 8 +- code/game/objects/items/dice.dm | 2 +- .../objects/items/implants/implant_storage.dm | 2 +- code/game/objects/items/melee/misc.dm | 8 +- code/game/objects/items/storage/backpack.dm | 2 +- code/game/objects/items/storage/bags.dm | 33 +- code/game/objects/items/storage/belt.dm | 18 +- .../objects/items/storage/boxes/food_boxes.dm | 6 +- .../items/storage/boxes/medical_boxes.dm | 2 +- .../items/storage/boxes/science_boxes.dm | 4 +- .../items/storage/boxes/service_boxes.dm | 4 +- code/game/objects/items/storage/fancy.dm | 16 +- code/game/objects/items/storage/garment.dm | 4 +- code/game/objects/items/storage/lockbox.dm | 2 +- code/game/objects/items/storage/medkit.dm | 20 +- code/game/objects/items/storage/sixpack.dm | 4 +- code/game/objects/items/storage/storage.dm | 12 +- code/game/objects/items/surgery_tray.dm | 26 - code/game/objects/items/tcg/tcg.dm | 2 +- code/game/objects/structures/secure_safe.dm | 2 +- code/game/objects/structures/toiletbong.dm | 6 +- code/modules/clothing/outfits/vv_outfit.dm | 3 +- .../under/accessories/_accessories.dm | 7 +- code/modules/explorer_drone/exodrone.dm | 5 +- code/modules/fishing/fishing_equipment.dm | 4 +- .../food_and_drinks/machinery/coffeemaker.dm | 2 +- .../food_and_drinks/machinery/griddle.dm | 10 +- code/modules/mining/lavaland/tendril_loot.dm | 2 - code/modules/mob/inventory.dm | 4 +- .../mob/living/carbon/human/inventory.dm | 5 +- code/modules/mob/living/living.dm | 15 +- code/modules/mod/modules/modules_general.dm | 5 +- code/modules/photography/photos/album.dm | 11 +- .../guns/ballistic/bows/bow_quivers.dm | 4 +- .../projectiles/guns/energy/dueling.dm | 2 +- code/modules/recycling/disposal/bin.dm | 12 +- .../modules/clothing/storage/belts.dm | 4 +- .../goofsec/code/sec_clothing_overrides.dm | 4 +- 53 files changed, 717 insertions(+), 831 deletions(-) diff --git a/code/__DEFINES/dcs/signals/signals_object.dm b/code/__DEFINES/dcs/signals/signals_object.dm index d65cb835116..442309289f0 100644 --- a/code/__DEFINES/dcs/signals/signals_object.dm +++ b/code/__DEFINES/dcs/signals/signals_object.dm @@ -138,8 +138,10 @@ #define COMSIG_ITEM_PICKUP "item_pickup" ///from base of obj/item/on_outfit_equip(): (mob/equipper, visuals_only, slot) #define COMSIG_ITEM_EQUIPPED_AS_OUTFIT "item_equip_as_outfit" -///from base of datum/storage/attempt_insert(): () +///from base of datum/storage/handle_enter(): (datum/storage/storage) #define COMSIG_ITEM_STORED "item_stored" +///from base of datum/storage/handle_exit(): (datum/storage/storage) +#define COMSIG_ITEM_UNSTORED "item_unstored" ///from base of obj/item/apply_fantasy_bonuses(): (bonus) #define COMSIG_ITEM_APPLY_FANTASY_BONUSES "item_apply_fantasy_bonuses" diff --git a/code/__HELPERS/atoms.dm b/code/__HELPERS/atoms.dm index 9845593c084..406ea75143c 100644 --- a/code/__HELPERS/atoms.dm +++ b/code/__HELPERS/atoms.dm @@ -314,16 +314,6 @@ rough example of the "cone" made by the 3 dirs checked /proc/pass(...) return -///Returns a list of the parents of all storage components that contain the target item -/proc/get_storage_locs(obj/item/target) - . = list() - if(!istype(target) || !(target.item_flags & IN_STORAGE)) - return - var/datum/storage/storage_datum = target.loc.atom_storage - if(!storage_datum) - return - . += storage_datum.real_location?.resolve() - /// Returns an x and y value require to reverse the transformations made to center an oversized icon /atom/proc/get_oversized_icon_offsets() if (pixel_x == 0 && pixel_y == 0) diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index acfa2e40f18..915bdea22d4 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -5,142 +5,134 @@ * If you're looking to create custom storage type behaviors, check ../subtypes */ /datum/storage - /// the actual item we're attached to - var/datum/weakref/parent - /// the actual item we're storing in - var/datum/weakref/real_location - - /// if this is set, only items, and their children, will fit - var/list/can_hold - /// if this is set, items, and their children, won't fit - var/list/cant_hold - /// if set, these items will be the exception to the max size of object that can fit. - var/list/exception_hold - /// if exception_hold is set, how many exception items can we hold at any one time? - var/exception_max = INFINITE - /// if set can only contain stuff with this single trait present. - var/list/can_hold_trait - - /// whether or not we should have those cute little animations + /** + * A reference to the atom linked to this storage object + * If the parent goes, we go. Will never be null. + */ + VAR_FINAL/atom/parent + /** + * A reference to the atom where the items are actually stored. + * By default this is parent. Should generally never be null. + * Sometimes it's not the parent, that's what is called "dissassociated storage". + * + * Do NOT set this directly, use set_real_location. + */ + VAR_FINAL/atom/real_location + + /// List of all the mobs currently viewing the contents of this storage. + VAR_PRIVATE/list/mob/is_using = list() + + /// The storage display screen object. + VAR_PRIVATE/atom/movable/screen/storage/boxes + /// The 'close button' screen object. + VAR_PRIVATE/atom/movable/screen/close/closer + + /// Typecache of items that can be inserted into this storage. + /// By default, all item types can be inserted (assuming other conditions are met). + /// Do not set directly, use set_holdable + VAR_FINAL/list/obj/item/can_hold + /// Typecache of items that cannot be inserted into this storage. + /// By default, no item types are barred from insertion. + /// Do not set directly, use set_holdable + VAR_FINAL/list/obj/item/cant_hold + /// Typecache of items that can always be inserted into this storage, regardless of size. + VAR_FINAL/list/obj/item/exception_hold + /// For use with an exception typecache: + /// The maximum amount of items of the exception type that can be inserted into this storage. + var/exception_max = INFINITY + + /// Determines whether we play a rustle animation when inserting/removing items. var/animated = TRUE + /// Determines whether we play a rustle sound when inserting/removing items. + var/rustle_sound = TRUE + /// The maximum amount of items that can be inserted into this storage. var/max_slots = 7 - /// max weight class for a single item being inserted + /// The largest weight class that can be inserted into this storage, inclusive. var/max_specific_storage = WEIGHT_CLASS_NORMAL - /// max combined weight classes the storage can hold - var/max_total_storage = 14 - - /// list of all the mobs currently viewing the contents - var/list/is_using = list() + /// Determines the maximum amount of weight that can be inserted into this storage. + /// Weight is calculated by the sum of all of our content's weight classes. + var/max_total_storage = WEIGHT_CLASS_SMALL * 7 + /// Whether the storage is currently locked (inaccessible). See [code/__DEFINES/storage.dm] var/locked = STORAGE_NOT_LOCKED - /// whether or not we should open when clicked + + /// Whether we open when attack_handed (clicked on with an empty hand). var/attack_hand_interact = TRUE - /// whether or not we allow storage objects of the same size inside + + /// Whether we allow storage objects of the same size inside. var/allow_big_nesting = FALSE - /// should we be allowed to pickup an object by clicking it + /// If TRUE, we can click on items with the storage object to pick them up and insert them. var/allow_quick_gather = FALSE - /// show we allow emptying all contents by using the storage object in hand + /// The mode for collection when allow_quick_gather is enabled. See [code/__DEFINES/storage.dm] + var/collection_mode = COLLECT_EVERYTHING + + /// If TRUE, we can use-in-hand the storage object to dump all of its contents. var/allow_quick_empty = FALSE - /// the mode for collection when allow_quick_gather is enabled - var/collection_mode = COLLECT_ONE + /// If we support smartly removing/inserting things from ourselves var/supports_smart_equip = TRUE - /// shows what we can hold in examine text + /// An additional description shown on double-examine. + /// Is autogenerated to the can_hold list if not set. var/can_hold_description - /// contents shouldn't be emped - var/emp_shielded - - /// you put things *in* a bag, but *on* a plate + /// The preposition used when inserting items into this storage. + /// IE: You put things *in* a bag, but *on* a plate. var/insert_preposition = "in" - /// don't show any chat messages regarding inserting items + /// If TRUE, chat messages for inserting/removing items will not be shown. var/silent = FALSE - /// same as above but only for the user, useful to cut on chat spam without removing feedback for other players + /// Same as above but only for the user. + /// Useful to cut on chat spam without removing feedback for other players. var/silent_for_user = FALSE - /// play a rustling sound when interacting with the bag - var/rustle_sound = TRUE - /// alt click takes an item out instead of opening up storage + /// if TRUE, alt-click takes an item out instantly rather than opening up storage. var/quickdraw = FALSE - /// instead of displaying multiple items of the same type, display them as numbered contents + /// Instead of displaying multiple items of the same type, display them as numbered contents. var/numerical_stacking = FALSE - /// storage display object - var/atom/movable/screen/storage/boxes - /// close button object - var/atom/movable/screen/close/closer - - /// maximum amount of columns a storage object can have + /// Maximum amount of columns a storage object can have var/screen_max_columns = 7 + /// Maximum amount of rows a storage object can have var/screen_max_rows = INFINITY - /// pixel location of the boxes and close button + /// X-pixel location of the boxes and close button var/screen_pixel_x = 16 + /// Y-pixel location of the boxes and close button var/screen_pixel_y = 16 - /// where storage starts being rendered, screen_loc wise + /// Where storage starts being rendered, x-screen_loc wise var/screen_start_x = 4 + /// Where storage starts being rendered, y-screen_loc wise var/screen_start_y = 2 - var/datum/weakref/modeswitch_action_ref + /// Ref to the item action that toggles collectmode. + VAR_PRIVATE/datum/action/item_action/storage_gather_mode/modeswitch_action - /// If true shows the contents of the storage in open_storage + /// If TRUE, shows the contents of the storage in open_storage var/display_contents = TRUE -/datum/storage/New(atom/parent, max_slots, max_specific_storage, max_total_storage, numerical_stacking, allow_quick_gather, allow_quick_empty, collection_mode, attack_hand_interact) - boxes = new(null, null, src) - closer = new(null, null, src) - - src.parent = WEAKREF(parent) - src.real_location = src.parent - src.max_slots = max_slots || src.max_slots - src.max_specific_storage = max_specific_storage || src.max_specific_storage - src.max_total_storage = max_total_storage || src.max_total_storage - src.numerical_stacking = numerical_stacking || src.numerical_stacking - src.allow_quick_gather = allow_quick_gather || src.allow_quick_gather - src.allow_quick_empty = allow_quick_empty || src.allow_quick_empty - src.collection_mode = collection_mode || src.collection_mode - src.attack_hand_interact = attack_hand_interact || src.attack_hand_interact - - var/atom/resolve_parent = src.parent?.resolve() - var/atom/resolve_location = src.real_location?.resolve() - - if(!resolve_parent) - stack_trace("storage could not resolve parent weakref") +/datum/storage/New( + atom/parent, + max_slots = src.max_slots, + max_specific_storage = src.max_specific_storage, + max_total_storage = src.max_total_storage, +) + if(!istype(parent)) + stack_trace("Storage datum ([type]) created without a [isnull(parent) ? "null parent" : "invalid parent ([parent.type])"]!") qdel(src) return - if(!resolve_location) - stack_trace("storage could not resolve location weakref") - qdel(src) - return - - RegisterSignals(resolve_parent, list(COMSIG_ATOM_ATTACK_PAW, COMSIG_ATOM_ATTACK_HAND), PROC_REF(on_attack)) - RegisterSignal(resolve_parent, COMSIG_MOUSEDROP_ONTO, PROC_REF(on_mousedrop_onto)) - RegisterSignal(resolve_parent, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(on_mousedropped_onto)) - - RegisterSignal(resolve_parent, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) - RegisterSignal(resolve_parent, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby)) - RegisterSignal(resolve_parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(on_preattack)) - RegisterSignal(resolve_parent, COMSIG_OBJ_DECONSTRUCT, PROC_REF(on_deconstruct)) - - RegisterSignal(resolve_parent, COMSIG_ITEM_ATTACK_SELF, PROC_REF(mass_empty)) - - RegisterSignals(resolve_parent, list(COMSIG_CLICK_ALT, COMSIG_ATOM_ATTACK_GHOST, COMSIG_ATOM_ATTACK_HAND_SECONDARY), PROC_REF(open_storage_on_signal)) - RegisterSignal(resolve_parent, COMSIG_ATOM_ATTACKBY_SECONDARY, PROC_REF(open_storage_attackby_secondary)) - - RegisterSignal(resolve_location, COMSIG_ATOM_ENTERED, PROC_REF(handle_enter)) - RegisterSignal(resolve_location, COMSIG_ATOM_EXITED, PROC_REF(handle_exit)) - RegisterSignal(resolve_parent, COMSIG_MOVABLE_MOVED, PROC_REF(close_distance)) - RegisterSignal(resolve_parent, COMSIG_ITEM_EQUIPPED, PROC_REF(update_actions)) + boxes = new(null, null, src) + closer = new(null, null, src) - RegisterSignal(resolve_parent, COMSIG_TOPIC, PROC_REF(topic_handle)) + set_parent(parent) + set_real_location(parent) - RegisterSignal(resolve_parent, COMSIG_ATOM_EXAMINE, PROC_REF(handle_examination)) - RegisterSignal(resolve_parent, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(handle_extra_examination)) + src.max_slots = max_slots + src.max_specific_storage = max_specific_storage + src.max_total_storage = max_total_storage orient_to_hud() @@ -173,15 +165,11 @@ if(!istype(arrived)) return - var/atom/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - - resolve_parent.update_appearance(UPDATE_ICON_STATE) - arrived.item_flags |= IN_STORAGE refresh_views() arrived.on_enter_storage(src) + SEND_SIGNAL(arrived, COMSIG_ITEM_STORED, src) + parent.update_appearance() /// Automatically ran on all object removals: flag marking and view refreshing. /datum/storage/proc/handle_exit(datum/source, obj/item/gone) @@ -190,67 +178,97 @@ if(!istype(gone)) return - var/atom/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - - resolve_parent.update_appearance(UPDATE_ICON_STATE) - gone.item_flags &= ~IN_STORAGE remove_and_refresh(gone) gone.on_exit_storage(src) + SEND_SIGNAL(gone, COMSIG_ITEM_UNSTORED, src) + parent.update_appearance() + +/// Set the passed atom as the parent +/datum/storage/proc/set_parent(atom/new_parent) + PRIVATE_PROC(TRUE) + + ASSERT(isnull(parent)) + + parent = new_parent + // a few of theses should probably be on the real_location rather than the parent + RegisterSignals(parent, list(COMSIG_ATOM_ATTACK_PAW, COMSIG_ATOM_ATTACK_HAND), PROC_REF(on_attack)) + RegisterSignal(parent, COMSIG_MOUSEDROP_ONTO, PROC_REF(on_mousedrop_onto)) + RegisterSignal(parent, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(on_mousedropped_onto)) + RegisterSignal(parent, COMSIG_ATOM_ATTACKBY, PROC_REF(on_attackby)) + RegisterSignal(parent, COMSIG_ITEM_PRE_ATTACK, PROC_REF(on_preattack)) + RegisterSignal(parent, COMSIG_ITEM_ATTACK_SELF, PROC_REF(mass_empty)) + RegisterSignals(parent, list(COMSIG_CLICK_ALT, COMSIG_ATOM_ATTACK_GHOST, COMSIG_ATOM_ATTACK_HAND_SECONDARY), PROC_REF(open_storage_on_signal)) + RegisterSignal(parent, COMSIG_ATOM_ATTACKBY_SECONDARY, PROC_REF(open_storage_attackby_secondary)) + RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(close_distance)) + RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(update_actions)) + RegisterSignal(parent, COMSIG_TOPIC, PROC_REF(topic_handle)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE, PROC_REF(handle_examination)) + RegisterSignal(parent, COMSIG_ATOM_EXAMINE_MORE, PROC_REF(handle_extra_examination)) + RegisterSignal(parent, COMSIG_OBJ_DECONSTRUCT, PROC_REF(on_deconstruct)) + RegisterSignal(parent, COMSIG_ATOM_EMP_ACT, PROC_REF(on_emp_act)) /** * Sets where items are physically being stored in the case it shouldn't be on the parent. * - * @param atom/real the new real location of the datum - * @param should_drop if TRUE, all the items in the old real location will be dropped + * Does not handle moving any existing items, that must be done manually. + * + * Arguments + * * atom/new_real_location - the new real location of the datum + * * should_drop - if TRUE, all the items in the old real location will be dropped. */ -/datum/storage/proc/set_real_location(atom/real, should_drop = FALSE) - if(!real) - return - - var/atom/resolve_location = src.real_location?.resolve() - if(!resolve_location) - return - - var/atom/resolve_parent = src.parent?.resolve() - if(!resolve_parent) +/datum/storage/proc/set_real_location(atom/new_real_location, should_drop = FALSE) + if(!isnull(real_location)) + UnregisterSignal(real_location, list( + COMSIG_ATOM_ENTERED, + COMSIG_ATOM_EXITED, + COMSIG_QDELETING, + COMSIG_ATOM_EMP_ACT, + )) + real_location.flags_1 &= ~HAS_DISASSOCIATED_STORAGE_1 + if(should_drop) + remove_all() + + if(isnull(new_real_location)) return - if(should_drop) - remove_all(get_turf(resolve_parent)) + real_location = new_real_location + if(real_location != parent) + real_location.flags_1 |= HAS_DISASSOCIATED_STORAGE_1 + RegisterSignal(real_location, COMSIG_ATOM_ENTERED, PROC_REF(handle_enter)) + RegisterSignal(real_location, COMSIG_ATOM_EXITED, PROC_REF(handle_exit)) + RegisterSignal(real_location, COMSIG_QDELETING, PROC_REF(real_location_deleted)) - resolve_location.flags_1 &= ~HAS_DISASSOCIATED_STORAGE_1 - real.flags_1 |= HAS_DISASSOCIATED_STORAGE_1 - - UnregisterSignal(resolve_location, list(COMSIG_ATOM_ENTERED, COMSIG_ATOM_EXITED)) - - RegisterSignal(real, COMSIG_ATOM_ENTERED, PROC_REF(handle_enter)) - RegisterSignal(real, COMSIG_ATOM_EXITED, PROC_REF(handle_exit)) +/// Signal handler for when the real location is deleted. +/datum/storage/proc/real_location_deleted(datum/deleting_real_location) + SIGNAL_HANDLER - real_location = WEAKREF(real) + set_real_location(null) /datum/storage/proc/topic_handle(datum/source, user, href_list) SIGNAL_HANDLER + if(isnull(can_hold_description)) + return + if(href_list["show_valid_pocket_items"]) - handle_show_valid_items(source, user) + to_chat(user, span_notice("[source] can hold: [can_hold_description]")) /datum/storage/proc/handle_examination(datum/source, mob/user, list/examine_list) SIGNAL_HANDLER - if(!isnull(can_hold_description)) - examine_list += span_notice("You can examine this further to check what kind of extra items it can hold.") + if(isnull(can_hold_description)) + return + + examine_list += span_notice("You can examine this further to check what kind of extra items it can hold.") /datum/storage/proc/handle_extra_examination(datum/source, mob/user, list/examine_list) SIGNAL_HANDLER - if(!isnull(can_hold_description)) - examine_list += handle_show_valid_items(source, user) + if(isnull(can_hold_description)) + return -/datum/storage/proc/handle_show_valid_items(datum/source, user) - to_chat(user, span_notice("[source] can hold: [can_hold_description]")) + examine_list += span_notice("[source] can hold: [can_hold_description]") /// Almost 100% of the time the lists passed into set_holdable are reused for each instance /// Just fucking cache it 4head @@ -261,21 +279,22 @@ /// ~Lemon GLOBAL_LIST_EMPTY(cached_storage_typecaches) -/datum/storage/proc/set_holdable(list/can_hold_list = null, list/cant_hold_list = null) - if(!islist(can_hold_list)) +/datum/storage/proc/set_holdable(list/can_hold_list, list/cant_hold_list) + if(!isnull(can_hold_list) && !islist(can_hold_list)) can_hold_list = list(can_hold_list) - if(!islist(cant_hold_list)) + if(!isnull(cant_hold_list) && !islist(cant_hold_list)) cant_hold_list = list(cant_hold_list) - can_hold_description = generate_hold_desc(can_hold_list) + if (!isnull(can_hold_list)) + if(isnull(can_hold_description)) + can_hold_description = generate_hold_desc(can_hold_list) - if (can_hold_list) var/unique_key = can_hold_list.Join("-") if(!GLOB.cached_storage_typecaches[unique_key]) GLOB.cached_storage_typecaches[unique_key] = typecacheof(can_hold_list) can_hold = GLOB.cached_storage_typecaches[unique_key] - if (cant_hold_list != null) + if (!isnull(cant_hold_list)) var/unique_key = cant_hold_list.Join("-") if(!GLOB.cached_storage_typecaches[unique_key]) GLOB.cached_storage_typecaches[unique_key] = typecacheof(cant_hold_list) @@ -285,8 +304,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/generate_hold_desc(can_hold_list) var/list/desc = list() - for(var/valid_type in can_hold_list) - var/obj/item/valid_item = valid_type + for(var/obj/item/valid_item as anything in can_hold_list) desc += "\a [initial(valid_item.name)]" return "\n\t[span_notice("[desc.Join("\n\t")]")]" @@ -295,21 +313,18 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/update_actions(atom/source, mob/equipper, slot) SIGNAL_HANDLER - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) + if(!allow_quick_gather) + QDEL_NULL(modeswitch_action) return - - if(!istype(resolve_parent) || !allow_quick_gather) - QDEL_NULL(modeswitch_action_ref) + if(!isnull(modeswitch_action)) return - - var/datum/action/existing = modeswitch_action_ref?.resolve() - if(!QDELETED(existing)) + if(!isitem(parent)) return - var/datum/action/modeswitch_action = resolve_parent.add_item_action(/datum/action/item_action/storage_gather_mode) + var/obj/item/item_parent = parent + modeswitch_action = item_parent.add_item_action(/datum/action/item_action/storage_gather_mode) RegisterSignal(modeswitch_action, COMSIG_ACTION_TRIGGER, PROC_REF(action_trigger)) - modeswitch_action_ref = WEAKREF(modeswitch_action) + RegisterSignal(modeswitch_action, COMSIG_QDELETING, PROC_REF(action_deleted)) /// Refreshes and item to be put back into the real world, out of storage. /datum/storage/proc/reset_item(obj/item/thing) @@ -321,33 +336,23 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) thing.maptext = "" /** - * Checks if an item is capable of being inserted into the storage + * Checks if an item is capable of being inserted into the storage. * - * @param obj/item/to_insert the item we're checking - * @param messages if TRUE, will print out a message if the item is not valid - * @param force bypass locked storage up to a certain level. See [code/__DEFINES/storage.dm] + * Arguments + * * obj/item/to_insert - the item we're checking + * * messages - if TRUE, will print out a message if the item is not valid + * * force - bypass locked storage up to a certain level. See [code/__DEFINES/storage.dm] */ /datum/storage/proc/can_insert(obj/item/to_insert, mob/user, messages = TRUE, force = STORAGE_NOT_LOCKED) - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return - - if(QDELETED(to_insert)) - return FALSE - - if(!isitem(to_insert)) + if(QDELETED(to_insert) || !istype(to_insert)) return FALSE if(locked > force) - if(user && messages) + if(messages && user) user.balloon_alert(user, "closed!") return FALSE - if((to_insert == resolve_parent) || (to_insert == real_location)) + if((to_insert == parent) || (to_insert == real_location)) return FALSE if(to_insert.w_class > max_specific_storage) @@ -355,52 +360,45 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(messages && user) user.balloon_alert(user, "too big!") return FALSE - if(exception_max != INFINITE && exception_max <= exception_count()) + if(exception_max <= get_exception_count()) if(messages && user) user.balloon_alert(user, "no room!") return FALSE - if(resolve_location.contents.len >= max_slots) + if(real_location.contents.len >= max_slots) if(messages && user && !silent_for_user) user.balloon_alert(user, "no room!") return FALSE - var/total_weight = to_insert.w_class - - for(var/obj/item/thing in resolve_location) - total_weight += thing.w_class - - if(total_weight > max_total_storage) + if(to_insert.w_class + get_total_weight() > max_total_storage) if(messages && user && !silent_for_user) user.balloon_alert(user, "no room!") return FALSE - if(length(can_hold)) - if(!is_type_in_typecache(to_insert, can_hold)) - if(messages && user) - user.balloon_alert(user, "can't hold!") - return FALSE - - if(is_type_in_typecache(to_insert, cant_hold) || HAS_TRAIT(to_insert, TRAIT_NO_STORAGE_INSERT) || (can_hold_trait && !HAS_TRAIT(to_insert, can_hold_trait))) + var/can_hold_it = isnull(can_hold) || is_type_in_typecache(to_insert, can_hold) + var/cant_hold_it = is_type_in_typecache(to_insert, cant_hold) + var/trait_says_no = HAS_TRAIT(to_insert, TRAIT_NO_STORAGE_INSERT) + if(!can_hold_it || cant_hold_it || trait_says_no) if(messages && user) user.balloon_alert(user, "can't hold!") return FALSE if(HAS_TRAIT(to_insert, TRAIT_NODROP)) - if(messages) + if(messages && user) user.balloon_alert(user, "stuck on your hand!") return FALSE - var/datum/storage/biggerfish = resolve_parent.loc.atom_storage // this is valid if the container our resolve_parent is being held in is a storage item - - if(biggerfish && biggerfish.max_specific_storage < max_specific_storage) + // this is valid if the container our location is being held in is a storage item + var/datum/storage/bigger_fish = parent.loc.atom_storage + if(bigger_fish && bigger_fish.max_specific_storage < max_specific_storage) if(messages && user) - user.balloon_alert(user, "[lowertext(resolve_parent.loc.name)] is in the way!") + user.balloon_alert(user, "[lowertext(parent.loc.name)] is in the way!") return FALSE - if(istype(resolve_parent)) - var/datum/storage/item_storage = to_insert.atom_storage - if((to_insert.w_class >= resolve_parent.w_class) && item_storage && !allow_big_nesting) + if(isitem(parent)) + var/obj/item/item_parent = parent + var/datum/storage/smaller_fish = to_insert.atom_storage + if(smaller_fish && !allow_big_nesting && to_insert.w_class >= item_parent.w_class) if(messages && user) user.balloon_alert(user, "too big!") return FALSE @@ -408,63 +406,60 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) return TRUE /// Returns a count of how many items held due to exception_hold we have -/datum/storage/proc/exception_count() - var/obj/item/storage = real_location?.resolve() +/datum/storage/proc/get_exception_count() var/count = 0 - for(var/obj/item/thing in storage) + for(var/obj/item/thing in real_location) if(thing.w_class > max_specific_storage && is_type_in_typecache(thing, exception_hold)) count += 1 return count +/// Returns a sum of all of our content's weight classes +/datum/storage/proc/get_total_weight() + var/total_weight = 0 + for(var/obj/item/thing in real_location) + total_weight += thing.w_class + return total_weight + /** * Attempts to insert an item into the storage * - * @param datum/source used by the signal handler - * @param obj/item/to_insert the item we're inserting - * @param mob/user the user who is inserting the item - * @param override see item_insertion_feedback() - * @param force bypass locked storage up to a certain level. See [code/__DEFINES/storage.dm] + * Arguments + * * obj/item/to_insert - the item we're inserting + * * mob/user - (optional) the user who is inserting the item. + * * override - see item_insertion_feedback() + * * force - bypass locked storage up to a certain level. See [code/__DEFINES/storage.dm] */ /datum/storage/proc/attempt_insert(obj/item/to_insert, mob/user, override = FALSE, force = STORAGE_NOT_LOCKED) - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return FALSE + SHOULD_NOT_SLEEP(TRUE) if(!can_insert(to_insert, user, force = force)) return FALSE - SEND_SIGNAL(resolve_location, COMSIG_STORAGE_STORED_ITEM, to_insert, user, force) - - to_insert.item_flags |= IN_STORAGE - to_insert.forceMove(resolve_location) + SEND_SIGNAL(parent, COMSIG_STORAGE_STORED_ITEM, to_insert, user, force) + to_insert.forceMove(real_location) item_insertion_feedback(user, to_insert, override) - resolve_location.update_appearance() - SEND_SIGNAL(to_insert, COMSIG_ITEM_STORED) + parent.update_appearance() return TRUE /** * Inserts every item in a given list, with a progress bar * - * @param mob/user the user who is inserting the items - * @param list/things the list of items to insert - * @param atom/thing_loc the location of the items (used to make sure an item hasn't moved during pickup) - * @param list/rejections a list used to make sure we only complain once about an invalid insertion - * @param datum/progressbar/progress the progressbar used to show the progress of the insertion + * Arguments + * * mob/user - the user who is inserting the items + * * list/things - the list of items to insert + * * atom/thing_loc - the location of the items (used to make sure an item hasn't moved during pickup) + * * list/rejections - a list used to make sure we only complain once about an invalid insertion + * * datum/progressbar/progress - the progressbar used to show the progress of the insertion */ /datum/storage/proc/handle_mass_pickup(mob/user, list/things, atom/thing_loc, list/rejections, datum/progressbar/progress) - var/obj/item/resolve_parent = parent?.resolve() - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_parent || !resolve_location) - return - for(var/obj/item/thing in things) things -= thing if(thing.loc != thing_loc) continue if(thing.type in rejections) // To limit bag spamming: any given type only complains once continue - if(!attempt_insert(thing, user, TRUE)) // Note can_be_inserted still makes noise when the answer is no - if(resolve_location.contents.len >= max_slots) + if(!attempt_insert(thing, user, override = TRUE)) // Note can_be_inserted still makes noise when the answer is no + if(real_location.contents.len >= max_slots) break rejections += thing.type // therefore full bags are still a little spammy continue @@ -479,15 +474,12 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /** * Provides visual feedback in chat for an item insertion * - * @param mob/user the user who is inserting the item - * @param obj/item/thing the item we're inserting - * @param override skip feedback, only do animation check + * Arguments + * * mob/user - the user who is inserting the item + * * obj/item/thing - the item we're inserting + * * override - skip feedback, only do animation check */ /datum/storage/proc/item_insertion_feedback(mob/user, obj/item/thing, override = FALSE) - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - if(animated) animate_parent() @@ -498,117 +490,94 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) return if(rustle_sound) - playsound(resolve_parent, SFX_RUSTLE, 50, TRUE, -5) + playsound(parent, SFX_RUSTLE, 50, TRUE, -5) if(!silent_for_user) - to_chat(user, span_notice("You put [thing] [insert_preposition]to [resolve_parent].")) + to_chat(user, span_notice("You put [thing] [insert_preposition]to [parent].")) + + for(var/mob/viewing in oviewers(user)) + if(in_range(user, viewing) || (thing?.w_class >= WEIGHT_CLASS_NORMAL)) + viewing.show_message(span_notice("[user] puts [thing] [insert_preposition]to [parent]."), MSG_VISUAL) - for(var/mob/viewing in oviewers(user, null)) - if(in_range(user, viewing)) - viewing.show_message(span_notice("[user] puts [thing] [insert_preposition]to [resolve_parent]."), MSG_VISUAL) - return - if(thing && thing.w_class >= 3) - viewing.show_message(span_notice("[user] puts [thing] [insert_preposition]to [resolve_parent]."), MSG_VISUAL) - return /** * Attempts to remove an item from the storage * Ignores removal do_afters. Only use this if you're doing it as part of a dumping action * - * @param obj/item/thing the object we're removing - * @param atom/newLoc where we're placing the item - * @param silent if TRUE, we won't play any exit sounds + * Arguments + * * obj/item/thing - the object we're removing + * * atom/remove_to_loc - where we're placing the item + * * silent - if TRUE, we won't play any exit sounds */ -/datum/storage/proc/attempt_remove(obj/item/thing, atom/newLoc, silent = FALSE) - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return +/datum/storage/proc/attempt_remove(obj/item/thing, atom/remove_to_loc, silent = FALSE) + SHOULD_NOT_SLEEP(TRUE) - if(istype(thing)) - if(ismob(resolve_parent.loc)) - var/mob/mobparent = resolve_parent.loc - thing.dropped(mobparent, TRUE) + if(istype(thing) && ismob(parent.loc)) + var/mob/mob_parent = parent.loc + thing.dropped(mob_parent, /*silent = */TRUE) - if(newLoc) + if(remove_to_loc) reset_item(thing) - thing.forceMove(newLoc) + thing.forceMove(remove_to_loc) if(rustle_sound && !silent) - playsound(resolve_parent, SFX_RUSTLE, 50, TRUE, -5) + playsound(parent, SFX_RUSTLE, 50, TRUE, -5) else thing.moveToNullspace() - thing.item_flags &= ~IN_STORAGE - if(animated) animate_parent() refresh_views() - - if(isobj(resolve_parent)) - resolve_parent.update_appearance() - + parent.update_appearance() return TRUE /** * Removes everything inside of our storage * - * @param atom/target where we're placing the item + * Arguments + * * atom/drop_loc - where we're placing the item */ -/datum/storage/proc/remove_all(atom/target) - var/obj/item/resolve_parent = parent?.resolve() - var/obj/item/resolve_location = real_location?.resolve() - 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 - if(!attempt_remove(thing, target, silent = TRUE)) +/datum/storage/proc/remove_all(atom/drop_loc = parent.drop_location()) + for(var/obj/item/thing in real_location) + if(!attempt_remove(thing, drop_loc, silent = TRUE)) continue thing.pixel_x = thing.base_pixel_x + rand(-8, 8) thing.pixel_y = thing.base_pixel_y + rand(-8, 8) - /** * Allows a mob to attempt to remove a single item from the storage * Allows for hooks into things like removal delays * - * @param mob/removing the mob doing the removing - * @param obj/item/thing the object we're removing - * @param atom/newLoc where we're placing the item - * @param silent if TRUE, we won't play any exit sounds + * Arguments + * * mob/removing - the mob doing the removing + * * obj/item/thing - the object we're removing + * * atom/remove_to_loc - where we're placing the item + * * silent - if TRUE, we won't play any exit sounds */ -/datum/storage/proc/remove_single(mob/removing, obj/item/thing, atom/newLoc, silent = FALSE) - if(!attempt_remove(thing, newLoc, silent)) - return FALSE - return TRUE +/datum/storage/proc/remove_single(mob/removing, obj/item/thing, atom/remove_to_loc, silent = FALSE) + return attempt_remove(thing, remove_to_loc, silent) /** * Removes only a specific type of item from our storage * - * @param type the type of item to remove - * @param amount how many we should attempt to pick up at one time - * @param check_adjacent if TRUE, we'll check adjacent locations for the item type - * @param force if TRUE, we'll bypass the check_adjacent check all together - * @param mob/user the user who is removing the items - * @param list/inserted a list passed to attempt_remove for ultimate removal + * Arguments + * * type - the type of item to remove + * * amount - how many we should attempt to pick up at one time + * * check_adjacent - if TRUE, we'll check adjacent locations for the item type + * * force - if TRUE, we'll bypass the check_adjacent check all together + * * mob/user - the user who is removing the items + * * list/inserted - (optional) allows consumers to pass a list to be filled with all removed items. */ /datum/storage/proc/remove_type(type, atom/destination, amount = INFINITY, check_adjacent = FALSE, force = FALSE, mob/user, list/inserted) - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return + if(!force && check_adjacent) + if(isnull(user) || !user.CanReach(destination) || !user.CanReach(parent)) + return FALSE - if(!force) - if(check_adjacent) - if(!user || !user.CanReach(destination) || !user.CanReach(resolve_location)) - return FALSE - var/list/taking = typecache_filter_list(resolve_location.contents, typecacheof(type)) + var/list/taking = typecache_filter_list(real_location.contents, typecacheof(type)) if(taking.len > amount) taking.len = amount + if(inserted) //duplicated code for performance, don't bother checking retval/checking for list every item. for(var/i in taking) if(attempt_remove(i, destination)) @@ -616,41 +585,34 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) else for(var/i in taking) attempt_remove(i, destination) + return TRUE /// Signal handler for remove_all() -/datum/storage/proc/mass_empty(datum/source, atom/location, force) +/datum/storage/proc/mass_empty(datum/source, mob/user) SIGNAL_HANDLER - if(!allow_quick_empty && !force) + if(!allow_quick_empty) return - remove_all(get_turf(location)) + remove_all(user.drop_location()) /** * Recursive proc to get absolutely EVERYTHING inside a storage item, including the contents of inner items. * - * @param list/interface the list we're adding objects to - * @param recursive whether or not we're checking inside of inner items + * Arguments + * * recursive - whether or not we're checking inside of inner items */ -/datum/storage/proc/return_inv(list/interface, recursive = TRUE) - if(!islist(interface)) - return FALSE - - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return - +/datum/storage/proc/return_inv(recursive = TRUE) var/list/ret = list() - ret |= resolve_location.contents - if(recursive) - for(var/i in ret.Copy()) - var/atom/atom = i - atom.atom_storage?.return_inv(ret, TRUE) + ret |= real_location.contents - interface |= ret + for(var/atom/found_thing as anything in real_location) + ret |= found_thing + if(recursive) + ret |= found_thing.atom_storage?.return_inv(ret, recursive = TRUE) - return TRUE + return ret /** * Resets an object, removes it from our screen, and refreshes the view. @@ -668,18 +630,14 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) reset_item(gone) refresh_views() -/// Signal handler for the emp_act() of all contents -/datum/storage/proc/on_emp_act(datum/source, severity) +/// Signal handler for emp_act to emp all contents +/datum/storage/proc/on_emp_act(datum/source, severity, protection) SIGNAL_HANDLER - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) + if(protection & EMP_PROTECT_CONTENTS) return - if(emp_shielded) - return - - for(var/atom/thing in resolve_location) + for(var/obj/item/thing in real_location) thing.emp_act(severity) /// Signal handler for preattack from an object. @@ -706,10 +664,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) * @param mob/user the user who is picking up the items */ /datum/storage/proc/collect_on_turf(obj/item/thing, mob/user) - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - var/atom/holder = thing.loc var/list/pick_up = holder.contents.Copy() @@ -718,13 +672,13 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) var/amount = length(pick_up) if(!amount) - resolve_parent.balloon_alert(user, "nothing to pick up!") + parent.balloon_alert(user, "nothing to pick up!") return var/datum/progressbar/progress = new(user, amount, thing.loc) var/list/rejections = list() - while(do_after(user, 1 SECONDS, resolve_parent, NONE, FALSE, CALLBACK(src, PROC_REF(handle_mass_pickup), user, pick_up.Copy(), thing.loc, rejections, progress))) + while(do_after(user, 1 SECONDS, parent, NONE, FALSE, CALLBACK(src, PROC_REF(handle_mass_pickup), user, pick_up.Copy(), thing.loc, rejections, progress))) stoplag(1) progress.end_progress() @@ -732,29 +686,23 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) var/list/current_contents = holder.contents.Copy() if(length(pick_up | current_contents) == length(current_contents)) return - resolve_parent.balloon_alert(user, "picked up") + parent.balloon_alert(user, "picked up") /// Signal handler for whenever we drag the storage somewhere. /datum/storage/proc/on_mousedrop_onto(datum/source, atom/over_object, mob/user) SIGNAL_HANDLER - var/obj/item/resolve_parent = parent?.resolve() - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_parent || !resolve_location) - return - if(ismecha(user.loc) || user.incapacitated() || !user.canUseStorage()) return - resolve_parent.add_fingerprint(user) + parent.add_fingerprint(user) if(istype(over_object, /atom/movable/screen/inventory/hand)) - - if(resolve_parent.loc != user) + if(real_location.loc != user) return var/atom/movable/screen/inventory/hand/hand = over_object - user.putItemFromInventoryInHandIfPossible(resolve_parent, hand.held_index) + user.putItemFromInventoryInHandIfPossible(parent, hand.held_index) else if(ismob(over_object)) if(over_object != user) @@ -772,30 +720,25 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) * @param mob/user the user who is dumping the contents */ /datum/storage/proc/dump_content_at(atom/dest_object, mob/user) - var/obj/item/resolve_parent = parent.resolve() - var/obj/item/resolve_location = real_location.resolve() - if(locked) user.balloon_alert(user, "closed!") return - if(!user.CanReach(resolve_parent) || !user.CanReach(dest_object)) + if(!user.CanReach(parent) || !user.CanReach(dest_object)) return - if(SEND_SIGNAL(dest_object, COMSIG_STORAGE_DUMP_CONTENT, resolve_location, user) & STORAGE_DUMP_HANDLED) + if(SEND_SIGNAL(dest_object, COMSIG_STORAGE_DUMP_CONTENT, src, user) & STORAGE_DUMP_HANDLED) return // Storage to storage transfer is instant if(dest_object.atom_storage) - to_chat(user, span_notice("You dump the contents of [resolve_parent] into [dest_object].")) + to_chat(user, span_notice("You dump the contents of [parent] into [dest_object].")) if(rustle_sound) - playsound(resolve_parent, SFX_RUSTLE, 50, TRUE, -5) + playsound(parent, SFX_RUSTLE, 50, TRUE, -5) - for(var/obj/item/to_dump in resolve_location) - if(to_dump.loc != resolve_location) - continue + for(var/obj/item/to_dump in real_location) dest_object.atom_storage.attempt_insert(to_dump, user) - resolve_parent.update_appearance() + parent.update_appearance() SEND_SIGNAL(src, COMSIG_STORAGE_DUMP_POST_TRANSFER, dest_object, user) return @@ -804,7 +747,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) return // Storage to loc transfer requires a do_after - to_chat(user, span_notice("You start dumping out the contents of [resolve_parent] onto [dest_object]...")) + to_chat(user, span_notice("You start dumping out the contents of [parent] onto [dest_object]...")) if(!do_after(user, 2 SECONDS, target = dest_object)) return @@ -814,10 +757,6 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/on_mousedropped_onto(datum/source, obj/item/dropping, mob/user) SIGNAL_HANDLER - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - if(!istype(dropping)) return if(dropping != user.get_active_held_item()) @@ -837,11 +776,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/on_attackby(datum/source, obj/item/thing, mob/user, params) SIGNAL_HANDLER - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - - if(!thing.attackby_storage_insert(src, resolve_parent, user)) + if(!thing.attackby_storage_insert(src, parent, user)) return if(iscyborg(user)) @@ -854,39 +789,32 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/on_attack(datum/source, mob/user) SIGNAL_HANDLER - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return if(!attack_hand_interact) return - if(user.active_storage == src && resolve_parent.loc == user) + if(user.active_storage == src && parent.loc == user) user.active_storage.hide_contents(user) hide_contents(user) return COMPONENT_CANCEL_ATTACK_CHAIN if(ishuman(user)) var/mob/living/carbon/human/hum = user - if(hum.l_store == resolve_parent && !hum.get_active_held_item()) - INVOKE_ASYNC(hum, TYPE_PROC_REF(/mob, put_in_hands), resolve_parent) + if(hum.l_store == parent && !hum.get_active_held_item()) + INVOKE_ASYNC(hum, TYPE_PROC_REF(/mob, put_in_hands), parent) hum.l_store = null return - if(hum.r_store == resolve_parent && !hum.get_active_held_item()) - INVOKE_ASYNC(hum, TYPE_PROC_REF(/mob, put_in_hands), resolve_parent) + if(hum.r_store == parent && !hum.get_active_held_item()) + INVOKE_ASYNC(hum, TYPE_PROC_REF(/mob, put_in_hands), parent) hum.r_store = null return - if(resolve_parent.loc == user) + if(parent.loc == user) INVOKE_ASYNC(src, PROC_REF(open_storage), user) return COMPONENT_CANCEL_ATTACK_CHAIN /// Generates the numbers on an item in storage to show stacking. /datum/storage/proc/process_numerical_display() - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return - var/list/toreturn = list() - for(var/obj/item/thing in resolve_location.contents) + for(var/obj/item/thing in real_location) var/total_amnt = 1 if(isstack(thing)) @@ -903,11 +831,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /// Updates the storage UI to fit all objects inside storage. /datum/storage/proc/orient_to_hud() - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return - - var/adjusted_contents = resolve_location.contents.len + var/adjusted_contents = real_location.contents.len //Numbered contents display var/list/datum/numbered_display/numbered_contents @@ -924,14 +848,10 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /// Generates the actual UI objects, their location, and alignments whenever we open storage up. /datum/storage/proc/orient_item_boxes(rows, cols, list/obj/item/numerical_display_contents) - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return - boxes.screen_loc = "[screen_start_x]:[screen_pixel_x],[screen_start_y]:[screen_pixel_y] to [screen_start_x+cols-1]:[screen_pixel_x],[screen_start_y+rows-1]:[screen_pixel_y]" var/current_x = screen_start_x var/current_y = screen_start_y - var/turf/our_turf = get_turf(resolve_location) + var/turf/our_turf = get_turf(real_location) if(islist(numerical_display_contents)) for(var/type in numerical_display_contents) @@ -953,7 +873,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) break else - for(var/obj/item in resolve_location) + for(var/obj/item in real_location) item.mouse_opacity = MOUSE_OPACITY_OPAQUE item.screen_loc = "[current_x]:[screen_pixel_x],[current_y]:[screen_pixel_y]" item.maptext = "" @@ -991,20 +911,12 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /// Opens the storage to the mob, showing them the contents to their UI. /datum/storage/proc/open_storage(mob/to_show) - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return FALSE - - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return FALSE - if(isobserver(to_show)) show_contents(to_show) return FALSE - if(!to_show.CanReach(resolve_parent)) - resolve_parent.balloon_alert(to_show, "can't reach!") + if(!to_show.CanReach(parent)) + parent.balloon_alert(to_show, "can't reach!") return FALSE if(!isliving(to_show) || to_show.incapacitated()) @@ -1012,12 +924,12 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(locked) if(!silent) - resolve_parent.balloon_alert(to_show, "closed!") + parent.balloon_alert(to_show, "closed!") return FALSE // If we're quickdrawing boys if(quickdraw && !to_show.get_active_held_item()) - var/obj/item/to_remove = locate() in resolve_location + var/obj/item/to_remove = locate() in real_location if(!to_remove) return TRUE @@ -1025,8 +937,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) INVOKE_ASYNC(src, PROC_REF(put_in_hands_async), to_show, to_remove) if(!silent) to_show.visible_message( - span_warning("[to_show] draws [to_remove] from [resolve_parent]!"), - span_notice("You draw [to_remove] from [resolve_parent]."), + span_warning("[to_show] draws [to_remove] from [parent]!"), + span_notice("You draw [to_remove] from [parent]."), ) return TRUE @@ -1038,7 +950,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) animate_parent() if(rustle_sound) - playsound(resolve_parent, SFX_RUSTLE, 50, TRUE, -5) + playsound(parent, SFX_RUSTLE, 50, TRUE, -5) return TRUE @@ -1054,12 +966,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /datum/storage/proc/close_distance(datum/source) SIGNAL_HANDLER - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - for(var/mob/user in can_see_contents()) - if (!user.CanReach(resolve_parent)) + if (!user.CanReach(parent)) hide_contents(user) /// Close the storage UI for everyone viewing us. @@ -1085,15 +993,14 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) /** * Show our storage to a mob. * - * @param mob/toshow the mob to show the storage to + * Arguments + * * mob/toshow - the mob to show the storage to * - * @returns FALSE if the show failed, TRUE otherwise + * Returns + * * FALSE if the show failed + * * TRUE otherwise */ /datum/storage/proc/show_contents(mob/toshow) - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return FALSE - if(!toshow.client) return FALSE @@ -1102,7 +1009,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) return FALSE if(toshow.active_storage != src && (toshow.stat == CONSCIOUS)) - for(var/obj/item/thing in resolve_location) + for(var/obj/item/thing in real_location) if(thing.on_found(toshow)) toshow.active_storage.hide_contents(toshow) @@ -1111,8 +1018,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) toshow.active_storage = src - if(ismovable(resolve_location)) - var/atom/movable/movable_loc = resolve_location + if(ismovable(real_location)) + var/atom/movable/movable_loc = real_location movable_loc.become_active_storage(src) orient_to_hud() @@ -1121,39 +1028,41 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) toshow.client.screen |= boxes toshow.client.screen |= closer - toshow.client.screen |= resolve_location.contents + toshow.client.screen |= real_location.contents return TRUE /** * Hide our storage from a mob. * - * @param mob/toshow the mob to hide the storage from + * Arguments + * * mob/toshow - the mob to hide the storage from */ -/datum/storage/proc/hide_contents(mob/toshow) - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return - - if(!toshow.client) +/datum/storage/proc/hide_contents(mob/to_hide) + if(!to_hide.client) return TRUE - if(toshow.active_storage == src) - toshow.active_storage = null + if(to_hide.active_storage == src) + to_hide.active_storage = null - if(!length(is_using) && ismovable(resolve_location)) - var/atom/movable/movable_loc = resolve_location + if(!length(is_using) && ismovable(real_location)) + var/atom/movable/movable_loc = real_location movable_loc.lose_active_storage(src) - is_using -= toshow + is_using -= to_hide - toshow.client.screen -= boxes - toshow.client.screen -= closer - toshow.client.screen -= resolve_location.contents + to_hide.client.screen -= boxes + to_hide.client.screen -= closer + to_hide.client.screen -= real_location.contents + return TRUE -/datum/storage/proc/action_trigger(datum/signal_source, datum/action/source) +/datum/storage/proc/action_trigger(datum/source, datum/action/triggered) SIGNAL_HANDLER - toggle_collection_mode(source.owner) - return TRUE + toggle_collection_mode(triggered.owner) + +/datum/storage/proc/action_deleted(datum/source) + SIGNAL_HANDLER + + modeswitch_action = null /** * Toggles the collectmode of our storage. @@ -1161,25 +1070,17 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) * @param mob/toshow the mob toggling us */ /datum/storage/proc/toggle_collection_mode(mob/user) - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - - collection_mode = (collection_mode+1)%3 + collection_mode = (collection_mode + 1) % 3 switch(collection_mode) if(COLLECT_SAME) - resolve_parent.balloon_alert(user, "will now only pick up a single type") + parent.balloon_alert(user, "will now only pick up a single type") if(COLLECT_EVERYTHING) - resolve_parent.balloon_alert(user, "will now pick up everything") + parent.balloon_alert(user, "will now pick up everything") if(COLLECT_ONE) - resolve_parent.balloon_alert(user, "will now pick up one at a time") + parent.balloon_alert(user, "will now pick up one at a time") /// Gives a spiffy animation to our parent to represent opening and closing. /datum/storage/proc/animate_parent() - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - - var/matrix/old_matrix = resolve_parent.transform - animate(resolve_parent, time = 1.5, loop = 0, transform = resolve_parent.transform.Scale(1.07, 0.9)) + var/matrix/old_matrix = parent.transform + animate(parent, time = 1.5, loop = 0, transform = parent.transform.Scale(1.07, 0.9)) animate(time = 2, transform = old_matrix) diff --git a/code/datums/storage/subtypes/bag_of_holding.dm b/code/datums/storage/subtypes/bag_of_holding.dm index 9e3a486cdcd..5abc171e2cb 100644 --- a/code/datums/storage/subtypes/bag_of_holding.dm +++ b/code/datums/storage/subtypes/bag_of_holding.dm @@ -5,33 +5,40 @@ allow_big_nesting = TRUE /datum/storage/bag_of_holding/attempt_insert(obj/item/to_insert, mob/user, override, force) - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - var/list/obj/item/storage/backpack/holding/matching = typecache_filter_list(to_insert.get_all_contents(), typecacheof(/obj/item/storage/backpack/holding)) - matching -= resolve_parent + matching -= parent + matching -= real_location - if((istype(to_insert, /obj/item/storage/backpack/holding) || matching.len) && can_insert(to_insert, user)) - INVOKE_ASYNC(src, PROC_REF(recursive_insertion), to_insert, user, resolve_parent) - return + if((istype(to_insert, /obj/item/storage/backpack/holding) || length(matching)) && can_insert(to_insert, user)) + INVOKE_ASYNC(src, PROC_REF(recursive_insertion), to_insert, user) + return FALSE return ..() -/datum/storage/bag_of_holding/proc/recursive_insertion(obj/item/to_insert, mob/living/user, atom/resolve_parent) +/datum/storage/bag_of_holding/proc/recursive_insertion(obj/item/to_insert, mob/living/user) var/safety = tgui_alert(user, "Doing this will have extremely dire consequences for the station and its crew. Be sure you know what you're doing.", "Put in [to_insert.name]?", list("Proceed", "Abort")) - if(safety != "Proceed" || QDELETED(to_insert) || QDELETED(resolve_parent) || QDELETED(user) || !iscarbon(user) || !user.can_perform_action(resolve_parent, NEED_DEXTERITY) || !can_insert(to_insert, user)) + if(safety != "Proceed" \ + || QDELETED(to_insert) \ + || QDELETED(parent) \ + || QDELETED(real_location) \ + || QDELETED(user) \ + || !user.can_perform_action(parent, NEED_DEXTERITY) \ + || !can_insert(to_insert, user) \ + ) return - var/turf/loccheck = get_turf(resolve_parent) - to_chat(user, span_danger("The Bluespace interfaces of the two devices catastrophically malfunction!")) - qdel(to_insert) - playsound(loccheck,'sound/effects/supermatter.ogg', 200, TRUE) + var/turf/rift_loc = get_turf(parent) + user.visible_message( + span_userdanger("The Bluespace interfaces of the two devices catastrophically malfunction!"), + span_danger("The Bluespace interfaces of the two devices catastrophically malfunction!"), + ) + playsound(rift_loc, 'sound/effects/supermatter.ogg', 200, TRUE) - message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(loccheck)].") - user.log_message("detonated a bag of holding at [loc_name(loccheck)].", LOG_ATTACK, color="red") + message_admins("[ADMIN_LOOKUPFLW(user)] detonated a bag of holding at [ADMIN_VERBOSEJMP(rift_loc)].") + user.log_message("detonated a bag of holding at [loc_name(rift_loc)].", LOG_ATTACK, color = "red") user.investigate_log("has been gibbed by a bag of holding recursive insertion.", INVESTIGATE_DEATHS) user.gib() - new/obj/boh_tear(loccheck) - qdel(resolve_parent) + new /obj/boh_tear(rift_loc) + qdel(to_insert) + qdel(parent) diff --git a/code/datums/storage/subtypes/cards.dm b/code/datums/storage/subtypes/cards.dm index 19360651dd3..8e6a2bfb369 100644 --- a/code/datums/storage/subtypes/cards.dm +++ b/code/datums/storage/subtypes/cards.dm @@ -5,61 +5,52 @@ max_specific_storage = WEIGHT_CLASS_TINY max_slots = 30 max_total_storage = WEIGHT_CLASS_TINY * 30 - -/datum/storage/tcg/New() - . = ..() - set_holdable(list(/obj/item/tcgcard)) -/datum/storage/tcg/attempt_remove(obj/item/thing, atom/newLoc, silent = FALSE) +/datum/storage/tcg/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() - handle_empty_deck() + set_holdable(/obj/item/tcgcard) -/datum/storage/tcg/show_contents(mob/to_show) +/datum/storage/tcg/attempt_remove(obj/item/thing, atom/remove_to_loc, silent = FALSE) . = ..() - - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) + if(!.) return - to_show.visible_message(span_notice("[to_show] starts to look through the contents of \the [resolve_parent]!"), \ - span_notice("You begin looking into the contents of \the [resolve_parent]!")) + var/obj/item/tcgcard_deck/deck = parent + var/obj/item/tcgcard/card = thing + card.flipped = deck.flipped + card.update_appearance(UPDATE_ICON_STATE) -/datum/storage/tcg/hide_contents() - . = ..() - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return + if(length(real_location.contents) == 0) + qdel(parent) - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return - - resolve_location.visible_message(span_notice("\the [resolve_parent] is shuffled after looking through it.")) - resolve_location.contents = shuffle(resolve_location.contents) - -/datum/storage/tcg/dump_content_at(atom/dest_object, mob/user) +/datum/storage/tcg/show_contents(mob/to_show) + // sometimes, show contents is called when the mob is already seeing the contents of the deck, to refresh the view. + // to avoid spam, we only show the message if they weren't already seeing the contents. + var/was_already_seeing = to_show.active_storage == src . = ..() - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - - if(!resolve_parent.contents.len) - qdel(resolve_parent) - -/datum/storage/tcg/proc/handle_empty_deck() - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - - var/obj/item/resolve_location = real_location?.resolve() - if(!real_location) - return - - //You can't have a deck of one card! - if(resolve_location.contents.len == 1) - var/obj/item/tcgcard_deck/deck = resolve_location - var/obj/item/tcgcard/card = resolve_location.contents[1] - attempt_remove(card, card.drop_location()) - card.flipped = deck.flipped - card.update_icon_state() - qdel(resolve_parent) + if(!.) + return . + if(!was_already_seeing) + to_show.visible_message( + span_notice("[to_show] starts to look through the contents of [parent]!"), + span_notice("You begin looking into the contents of [parent]."), + ) + return . + +/datum/storage/tcg/hide_contents(mob/to_hide) + // see above + var/was_actually_seeing = to_hide.active_storage == src + . = ..() + if(!.) + return . + if(QDELING(src)) + return . + if(was_actually_seeing) + real_location.visible_message(span_notice("[parent] is shuffled after looking through it.")) + real_location.contents = shuffle(real_location.contents) + return . diff --git a/code/datums/storage/subtypes/duffel_bag.dm b/code/datums/storage/subtypes/duffel_bag.dm index 02c3e99b78e..cfa073da5e5 100644 --- a/code/datums/storage/subtypes/duffel_bag.dm +++ b/code/datums/storage/subtypes/duffel_bag.dm @@ -10,7 +10,12 @@ silent = TRUE exception_max = 2 -/datum/storage/duffel/syndicate/New() +/datum/storage/duffel/syndicate/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() var/static/list/exception_type_list = list( diff --git a/code/datums/storage/subtypes/extract_inventory.dm b/code/datums/storage/subtypes/extract_inventory.dm index 8c571dbda1a..0fea7ffed63 100644 --- a/code/datums/storage/subtypes/extract_inventory.dm +++ b/code/datums/storage/subtypes/extract_inventory.dm @@ -8,31 +8,28 @@ rustle_sound = FALSE silent = TRUE -/datum/storage/extract_inventory/New() +/datum/storage/extract_inventory/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() set_holdable(/obj/item/food/monkeycube) - var/obj/item/slimecross/reproductive/parentSlimeExtract = parent?.resolve() - if(!parentSlimeExtract) - return - - if(!istype(parentSlimeExtract, /obj/item/slimecross/reproductive)) - stack_trace("storage subtype extract_inventory incompatible with [parentSlimeExtract]") + var/obj/item/slimecross/reproductive/parent_slime = parent + if(!istype(parent_slime, /obj/item/slimecross/reproductive)) + stack_trace("storage subtype ([type]) incompatible with [parent_slime] ([parent_slime.type])") qdel(src) /datum/storage/extract_inventory/proc/processCubes(mob/user) - var/obj/item/slimecross/reproductive/parentSlimeExtract = parent?.resolve() - if(!parentSlimeExtract) - return - - if(parentSlimeExtract.contents.len >= max_slots) + var/obj/item/slimecross/reproductive/parentSlimeExtract = parent + if(real_location.contents.len >= max_slots) QDEL_LIST(parentSlimeExtract.contents) createExtracts(user) /datum/storage/extract_inventory/proc/createExtracts(mob/user) - var/obj/item/slimecross/reproductive/parentSlimeExtract = parent?.resolve() - if(!parentSlimeExtract) - return + var/obj/item/slimecross/reproductive/parentSlimeExtract = parent var/cores = rand(1,4) playsound(parentSlimeExtract, 'sound/effects/splat.ogg', 40, TRUE) diff --git a/code/datums/storage/subtypes/fish_case.dm b/code/datums/storage/subtypes/fish_case.dm index bc16f1607bf..dbbb15f47eb 100644 --- a/code/datums/storage/subtypes/fish_case.dm +++ b/code/datums/storage/subtypes/fish_case.dm @@ -1,33 +1,48 @@ /datum/storage/fish_case max_slots = 1 max_specific_storage = WEIGHT_CLASS_HUGE - can_hold_trait = TRAIT_FISH_CASE_COMPATIBILE - can_hold_description = "fish and aquarium equipment" + can_hold_description = "Fish and aquarium equipment" -/** +/datum/storage/fish_case/can_insert(obj/item/to_insert, mob/user, messages, force) + . = ..() + if(!.) + return . + if(!HAS_TRAIT(to_insert, TRAIT_FISH_CASE_COMPATIBILE)) + if(messages && user) + user.balloon_alert(user, "can't hold!") + return FALSE + return . + +/* * Change the size of the storage item to match the inserted item's * Because of that, we also check if conditions to keep it inside another storage or pockets are still met. */ -/datum/storage/fish_case/handle_enter(obj/item/storage/fish_case/source, obj/item/arrived) +/datum/storage/fish_case/handle_enter(datum/source, obj/item/arrived) . = ..() - if(!istype(arrived) || arrived.w_class == source.w_class) + if(!isitem(parent) || !istype(arrived)) + return + var/obj/item/item_parent = parent + if(arrived.w_class <= item_parent.w_class) return - source.w_class = arrived.w_class - var/obj/item/resolve_parent = parent?.resolve() - if(resolve_parent?.item_flags & IN_STORAGE) - source.moveToNullspace() //temporarily remove source from its location so that attempt_insert may work correctly. - if(!resolve_parent.atom_storage?.attempt_insert(source, override = TRUE)) - source.forceMove(resolve_parent.drop_location()) - source.visible_message("[source] spills out of [resolve_parent] as it expands to hold [arrived]", vision_distance = 1) - else if(!isliving(source.loc)) + item_parent.w_class = arrived.w_class + // Since we're changing weight class we need to check if our storage's loc's storage can still hold us + // in the future we need a generic solution to this to solve a bunch of other exploits + var/datum/storage/loc_storage = item_parent.loc.atom_storage + if(!isnull(loc_storage) && !loc_storage.can_insert(item_parent)) + item_parent.forceMove(item_parent.loc.drop_location()) + item_parent.visible_message(span_warning("[item_parent] spills out of [item_parent.loc] as it expands to hold [arrived]!"), vision_distance = 1) return - var/mob/living/living_loc = source.loc - var/equipped_slot = living_loc.get_slot_by_item(source) - if(equipped_slot & (ITEM_SLOT_RPOCKET|ITEM_SLOT_LPOCKET) && source.w_class > WEIGHT_CLASS_SMALL) - source.forceMove(living_loc.drop_location()) - to_chat(living_loc, "[source] drops out of your pockets as it expands to hold [arrived]") -/datum/storage/fish_case/handle_exit(obj/item/storage/fish_case/source, obj/item/gone) + if(isliving(item_parent.loc)) + var/mob/living/living_loc = item_parent.loc + if((living_loc.get_slot_by_item(item_parent) & (ITEM_SLOT_RPOCKET|ITEM_SLOT_LPOCKET)) && item_parent.w_class > WEIGHT_CLASS_SMALL) + item_parent.forceMove(living_loc.drop_location()) + to_chat(living_loc, span_warning("[item_parent] drops out of your pockets as it expands to hold [arrived]!")) + return + +/datum/storage/fish_case/handle_exit(datum/source, obj/item/gone) . = ..() - if(istype(gone)) - source.w_class = initial(source.w_class) + if(!isitem(parent) || !istype(gone)) + return + var/obj/item/item_parent = parent + item_parent.w_class = initial(item_parent.w_class) diff --git a/code/datums/storage/subtypes/implant.dm b/code/datums/storage/subtypes/implant.dm index 998e19a587c..547e79ba81c 100644 --- a/code/datums/storage/subtypes/implant.dm +++ b/code/datums/storage/subtypes/implant.dm @@ -5,6 +5,11 @@ silent = TRUE allow_big_nesting = TRUE -/datum/storage/implant/New() +/datum/storage/implant/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() - set_holdable(cant_hold_list = list(/obj/item/disk/nuclear)) + set_holdable(cant_hold_list = /obj/item/disk/nuclear) diff --git a/code/datums/storage/subtypes/pockets.dm b/code/datums/storage/subtypes/pockets.dm index 4bd60ba57b6..67a8b2dda78 100644 --- a/code/datums/storage/subtypes/pockets.dm +++ b/code/datums/storage/subtypes/pockets.dm @@ -9,17 +9,13 @@ if(!.) return - var/obj/item/resolve_parent = parent?.resolve() - if(!resolve_parent) - return - if(!silent || override) return if(quickdraw) - to_chat(user, span_notice("You discreetly slip [to_insert] into [resolve_parent]. Right-click [resolve_parent] to remove it.")) + to_chat(user, span_notice("You discreetly slip [to_insert] into [parent]. Right-click to remove it.")) else - to_chat(user, span_notice("You discreetly slip [to_insert] into [resolve_parent].")) + to_chat(user, span_notice("You discreetly slip [to_insert] into [parent].")) /datum/storage/pockets/small max_slots = 1 @@ -31,7 +27,12 @@ max_specific_storage = WEIGHT_CLASS_TINY attack_hand_interact = FALSE -/datum/storage/pockets/small/fedora/New() +/datum/storage/pockets/small/fedora/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() var/static/list/exception_cache = typecacheof(list( /obj/item/katana, @@ -50,7 +51,12 @@ max_slots = 1 max_specific_storage = WEIGHT_CLASS_NORMAL -/datum/storage/pockets/chefhat/New() +/datum/storage/pockets/chefhat/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() set_holdable(list( /obj/item/clothing/head/mob_holder, @@ -71,7 +77,12 @@ quickdraw = TRUE silent = TRUE -/datum/storage/pockets/shoes/New() +/datum/storage/pockets/shoes/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() set_holdable(list( /obj/item/knife, @@ -108,61 +119,80 @@ /obj/item/toy/crayon/spraycan) ) -/datum/storage/pockets/shoes/clown/New() +/datum/storage/pockets/shoes/clown/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() - set_holdable(list( - /obj/item/knife, - /obj/item/spess_knife, - /obj/item/switchblade, - /obj/item/pen, - /obj/item/scalpel, - /obj/item/reagent_containers/syringe, - /obj/item/dnainjector, - /obj/item/reagent_containers/hypospray/medipen, - /obj/item/reagent_containers/dropper, - /obj/item/implanter, - /obj/item/screwdriver, - /obj/item/weldingtool/mini, - /obj/item/firing_pin, - /obj/item/suppressor, - /obj/item/ammo_box/magazine/m9mm, - /obj/item/ammo_box/magazine/m10mm, - /obj/item/ammo_box/magazine/m45, - /obj/item/ammo_casing, - /obj/item/lipstick, - /obj/item/clothing/mask/cigarette, - /obj/item/lighter, - /obj/item/match, - /obj/item/holochip, - /obj/item/toy/crayon, - /obj/item/bikehorn, - /obj/item/reagent_containers/cup/glass/flask), - list(/obj/item/screwdriver/power, - /obj/item/ammo_casing/rocket, - /obj/item/clothing/mask/cigarette/pipe, - /obj/item/toy/crayon/spraycan) - ) + set_holdable( + can_hold_list = list( + /obj/item/ammo_box/magazine/m10mm, + /obj/item/ammo_box/magazine/m45, + /obj/item/ammo_box/magazine/m9mm, + /obj/item/ammo_casing, + /obj/item/bikehorn, + /obj/item/clothing/mask/cigarette, + /obj/item/dnainjector, + /obj/item/firing_pin, + /obj/item/holochip, + /obj/item/implanter, + /obj/item/knife, + /obj/item/lighter, + /obj/item/lipstick, + /obj/item/match, + /obj/item/pen, + /obj/item/reagent_containers/cup/glass/flask, + /obj/item/reagent_containers/dropper, + /obj/item/reagent_containers/hypospray/medipen, + /obj/item/reagent_containers/syringe, + /obj/item/scalpel, + /obj/item/screwdriver, + /obj/item/spess_knife, + /obj/item/suppressor, + /obj/item/switchblade, + /obj/item/toy/crayon, + /obj/item/weldingtool/mini, + ), + cant_hold_list = list( + /obj/item/ammo_casing/rocket, + /obj/item/clothing/mask/cigarette/pipe, + /obj/item/screwdriver/power, + /obj/item/toy/crayon/spraycan, + ), + ) /datum/storage/pockets/pocketprotector max_slots = 3 max_specific_storage = WEIGHT_CLASS_TINY -/datum/storage/pockets/pocketprotector/New() +/datum/storage/pockets/pocketprotector/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() set_holdable(list( //Same items as a PDA /obj/item/pen, /obj/item/toy/crayon, /obj/item/lipstick, /obj/item/flashlight/pen, - /obj/item/clothing/mask/cigarette) - ) + /obj/item/lipstick, + )) /datum/storage/pockets/helmet max_slots = 2 quickdraw = TRUE max_total_storage = 6 -/datum/storage/pockets/helmet/New() +/datum/storage/pockets/helmet/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() set_holdable(list(/obj/item/reagent_containers/cup/glass/bottle/vodka, /obj/item/reagent_containers/cup/glass/bottle/molotov, @@ -175,7 +205,12 @@ max_total_storage = 5 // 2 small items + 1 tiny item, or 1 normal item + 1 small item max_slots = 3 -/datum/storage/pockets/void_cloak/New() +/datum/storage/pockets/void_cloak/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() set_holdable(list( /obj/item/ammo_box/strilka310/lionhunter, diff --git a/code/datums/storage/subtypes/rped.dm b/code/datums/storage/subtypes/rped.dm index 599d63fd7db..9931cff7372 100644 --- a/code/datums/storage/subtypes/rped.dm +++ b/code/datums/storage/subtypes/rped.dm @@ -32,13 +32,10 @@ /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) . = ..() + if(!.) + return . //we check how much of glass,plasteel & cable the user can insert if(isstack(to_insert)) @@ -49,12 +46,8 @@ var/obj/item/stack/the_stack = to_insert var/present_amount = 0 - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return FALSE - //we try to count & limit how much the user can insert of each type to prevent them from using it as an normal storage medium - for(var/obj/item/stack/stack_content in resolve_location.contents) + for(var/obj/item/stack/stack_content in real_location) //is user trying to insert any of these listed bluespace stuff if(is_type_in_list(to_insert, allowed_bluespace_types)) //if yes count total bluespace stuff is the RPED and then compare the total amount to the value the user is trying to insert @@ -83,44 +76,35 @@ 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) +/datum/storage/rped/mass_empty(datum/source, mob/user) + if(!allow_quick_empty) return - remove_lowest_tier(get_turf(location)) + remove_lowest_tier(user.drop_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 + * Arguments + * * atom/dump_loc - 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() +/datum/storage/rped/proc/remove_lowest_tier(atom/dump_loc = parent.drop_location()) 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 real_location) + parts_list += thing - 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...") + if(ismob(parent.loc)) + parent.balloon_alert(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)) + if(!attempt_remove(part, dump_loc, silent = TRUE)) continue part.pixel_x = part.base_pixel_x + rand(-8, 8) part.pixel_y = part.base_pixel_y + rand(-8, 8) diff --git a/code/datums/storage/subtypes/surgery_tray.dm b/code/datums/storage/subtypes/surgery_tray.dm index c5b07b15fe4..ef4c45efe90 100644 --- a/code/datums/storage/subtypes/surgery_tray.dm +++ b/code/datums/storage/subtypes/surgery_tray.dm @@ -4,7 +4,12 @@ max_slots = 14 animated = FALSE -/datum/storage/surgery_tray/New() +/datum/storage/surgery_tray/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() set_holdable(list( /obj/item/autopsy_scanner, @@ -13,6 +18,7 @@ /obj/item/cautery, /obj/item/circular_saw, /obj/item/clothing/mask/surgical, + /obj/item/clothing/suit/toggle/labcoat/hospitalgown, // NOVA EDIT ADDITION /obj/item/hemostat, /obj/item/razor, /obj/item/retractor, diff --git a/code/datums/storage/subtypes/trash.dm b/code/datums/storage/subtypes/trash.dm index 650dcf4bb49..b4f0e4353e3 100644 --- a/code/datums/storage/subtypes/trash.dm +++ b/code/datums/storage/subtypes/trash.dm @@ -1,14 +1,11 @@ /datum/storage/trash -/datum/storage/trash/remove_single(mob/removing, obj/item/thing, atom/newLoc, silent) - var/obj/item/resolve_location = real_location?.resolve() - if(!resolve_location) - return - - resolve_location.visible_message(span_notice("[removing] starts fishing around inside \the [resolve_location]."), - span_notice("You start digging around in \the [resolve_location] to try and pull something out.")) - if(!do_after(removing, 1.5 SECONDS, resolve_location)) - return +/datum/storage/trash/remove_single(mob/removing, obj/item/thing, atom/remove_to_loc, silent) + real_location.visible_message( + span_notice("[removing] starts fishing around inside [parent]."), + span_notice("You start digging around in [parent] to try and pull something out."), + ) + if(!do_after(removing, 1.5 SECONDS, parent)) + return FALSE return ..() - diff --git a/code/game/atom/atom_storage.dm b/code/game/atom/atom_storage.dm index 6273c28fc2e..24ab0887742 100644 --- a/code/game/atom/atom_storage.dm +++ b/code/game/atom/atom_storage.dm @@ -7,32 +7,34 @@ max_slots, max_specific_storage, max_total_storage, - numerical_stacking = FALSE, - allow_quick_gather = FALSE, - allow_quick_empty = FALSE, - collection_mode = COLLECT_ONE, - attack_hand_interact = TRUE, list/canhold, list/canthold, storage_type = /datum/storage, ) + RETURN_TYPE(/datum/storage) if(atom_storage) QDEL_NULL(atom_storage) - atom_storage = new storage_type(src, max_slots, max_specific_storage, max_total_storage, numerical_stacking, allow_quick_gather, collection_mode, attack_hand_interact) + atom_storage = new storage_type(src, max_slots, max_specific_storage, max_total_storage) if(canhold || canthold) atom_storage.set_holdable(canhold, canthold) return atom_storage -/// A quick and easy way to /clone/ a storage datum for an atom (does not copy over contents, only the datum details) +/** + * A quick and easy way to /clone/ a storage datum for an atom (does not copy over contents, only the datum details) + * + * Imperfect, does not copy over ALL variables, only important ones (max storage size, etc) + */ /atom/proc/clone_storage(datum/storage/cloning) + RETURN_TYPE(/datum/storage) + if(atom_storage) QDEL_NULL(atom_storage) - atom_storage = new cloning.type(src, cloning.max_slots, cloning.max_specific_storage, cloning.max_total_storage, cloning.numerical_stacking, cloning.allow_quick_gather, cloning.collection_mode, cloning.attack_hand_interact) + atom_storage = new cloning.type(src, cloning.max_slots, cloning.max_specific_storage, cloning.max_total_storage) if(cloning.can_hold || cloning.cant_hold) if(!atom_storage.can_hold && !atom_storage.cant_hold) //In the event that the can/can't hold lists are already in place (such as from storage objects added on initialize). diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 04895e528ae..c82164dd7f4 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -790,8 +790,7 @@ /obj/item/on_exit_storage(datum/storage/master_storage) . = ..() - var/atom/location = master_storage.real_location?.resolve() - do_drop_animation(location) + do_drop_animation(master_storage.parent) /obj/item/throw_impact(atom/hit_atom, datum/thrownthing/throwingdatum) if(QDELETED(hit_atom)) diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm index fd80d78223f..77cfa81c4df 100644 --- a/code/game/objects/items/crayons.dm +++ b/code/game/objects/items/crayons.dm @@ -691,12 +691,14 @@ /obj/item/storage/crayons/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/toy/crayon), - list( + atom_storage.set_holdable( + can_hold_list = /obj/item/toy/crayon, + cant_hold_list = list( /obj/item/toy/crayon/spraycan, /obj/item/toy/crayon/mime, /obj/item/toy/crayon/rainbow, - )) + ), + ) /obj/item/storage/crayons/PopulateContents() new /obj/item/toy/crayon/red(src) diff --git a/code/game/objects/items/dice.dm b/code/game/objects/items/dice.dm index 8fe83e2e380..2ef6c4e7aa8 100644 --- a/code/game/objects/items/dice.dm +++ b/code/game/objects/items/dice.dm @@ -13,7 +13,7 @@ /obj/item/storage/dice/Initialize(mapload) . = ..() atom_storage.allow_quick_gather = TRUE - atom_storage.set_holdable(list(/obj/item/dice)) + atom_storage.set_holdable(/obj/item/dice) /obj/item/storage/dice/PopulateContents() new /obj/item/dice/d4(src) diff --git a/code/game/objects/items/implants/implant_storage.dm b/code/game/objects/items/implants/implant_storage.dm index 76f6b2547f7..df83170be28 100644 --- a/code/game/objects/items/implants/implant_storage.dm +++ b/code/game/objects/items/implants/implant_storage.dm @@ -19,7 +19,7 @@ atom_storage.remove_all() implantee.visible_message(span_warning("A bluespace pocket opens around [src] as it exits [implantee], spewing out its contents and rupturing the surrounding tissue!")) implantee.apply_damage(20, BRUTE, BODY_ZONE_CHEST) - qdel(atom_storage) + QDEL_NULL(atom_storage) return ..() /obj/item/implant/storage/implant(mob/living/target, mob/user, silent = FALSE, force = FALSE) diff --git a/code/game/objects/items/melee/misc.dm b/code/game/objects/items/melee/misc.dm index 0f30507a905..73fd7dcec33 100644 --- a/code/game/objects/items/melee/misc.dm +++ b/code/game/objects/items/melee/misc.dm @@ -117,14 +117,10 @@ return ..() /obj/item/melee/sabre/on_exit_storage(datum/storage/container) - var/obj/item/storage/belt/sabre/sabre = container.real_location?.resolve() - if(istype(sabre)) - playsound(sabre, 'sound/items/unsheath.ogg', 25, TRUE) + playsound(container.parent, 'sound/items/unsheath.ogg', 25, TRUE) /obj/item/melee/sabre/on_enter_storage(datum/storage/container) - var/obj/item/storage/belt/sabre/sabre = container.real_location?.resolve() - if(istype(sabre)) - playsound(sabre, 'sound/items/sheath.ogg', 25, TRUE) + playsound(container.parent, 'sound/items/sheath.ogg', 25, TRUE) /obj/item/melee/sabre/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] is trying to cut off all [user.p_their()] limbs with [src]! it looks like [user.p_theyre()] trying to commit suicide!")) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 372be881257..66b1c0da99c 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -385,7 +385,7 @@ . = ..() AddElement(/datum/element/undertile, TRAIT_T_RAY_VISIBLE, INVISIBILITY_MAXIMUM, use_anchor = TRUE) // NOVA EDIT - Ghosts can't see smuggler's satchels atom_storage.max_total_storage = 15 - atom_storage.set_holdable(cant_hold_list = list(/obj/item/storage/backpack/satchel/flat)) //muh recursive backpacks) + atom_storage.set_holdable(cant_hold_list = /obj/item/storage/backpack/satchel/flat) //muh recursive backpacks /obj/item/storage/backpack/satchel/flat/PopulateContents() for(var/items in 1 to 4) diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 6c4c8a881e9..d72a57f07f1 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -49,7 +49,7 @@ atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL atom_storage.max_total_storage = 30 atom_storage.max_slots = 30 - atom_storage.set_holdable(cant_hold_list = list(/obj/item/disk/nuclear)) + atom_storage.set_holdable(cant_hold_list = /obj/item/disk/nuclear) atom_storage.supports_smart_equip = FALSE RegisterSignal(atom_storage, COMSIG_STORAGE_DUMP_POST_TRANSFER, PROC_REF(post_insertion)) @@ -137,7 +137,7 @@ atom_storage.numerical_stacking = TRUE atom_storage.allow_quick_empty = TRUE atom_storage.allow_quick_gather = TRUE - atom_storage.set_holdable(list(/obj/item/stack/ore)) + atom_storage.set_holdable(/obj/item/stack/ore) atom_storage.silent_for_user = TRUE /obj/item/storage/bag/ore/equipped(mob/user) @@ -245,8 +245,7 @@ /obj/item/grown, /obj/item/food/honeycomb, /obj/item/seeds, - )) -//////// + )) /obj/item/storage/bag/plants/portaseeder name = "portable seed extractor" @@ -290,20 +289,22 @@ icon_state = "sheetsnatcher" worn_icon_state = "satchel" - var/capacity = 300; //the number of sheets it can carry. + var/capacity = 300 //the number of sheets it can carry. /obj/item/storage/bag/sheetsnatcher/Initialize(mapload) . = ..() atom_storage.allow_quick_empty = TRUE atom_storage.allow_quick_gather = TRUE atom_storage.numerical_stacking = TRUE - atom_storage.set_holdable(list( + atom_storage.set_holdable( + can_hold_list = list( /obj/item/stack/sheet - ), - list( + ), + cant_hold_list = list( /obj/item/stack/sheet/mineral/sandstone, /obj/item/stack/sheet/mineral/wood, - )) + ), + ) atom_storage.max_total_storage = capacity / 2 // ----------------------------- @@ -373,7 +374,7 @@ /obj/item/storage/box/matches, /obj/item/storage/fancy, /obj/item/trash, - )) //Should cover: Bottles, Beakers, Bowls, Booze, Glasses, Food, Food Containers, Food Trash, Organs, Tobacco Products, Lighters, and Kitchen Tools. + )) //Should cover: Bottles, Beakers, Bowls, Booze, Glasses, Food, Food Containers, Food Trash, Organs, Tobacco Products, Lighters, and Kitchen Tools. atom_storage.insert_preposition = "on" atom_storage.max_slots = 7 @@ -457,7 +458,7 @@ /obj/item/reagent_containers/medigel, /obj/item/reagent_containers/pill, /obj/item/reagent_containers/syringe, - )) + )) /* * Biowaste bag (mostly for virologists) @@ -487,7 +488,7 @@ /obj/item/reagent_containers/cup/tube, /obj/item/reagent_containers/hypospray/medipen, /obj/item/reagent_containers/syringe, - )) + )) /* * Science bag (mostly for xenobiologists) @@ -518,7 +519,7 @@ /obj/item/reagent_containers/syringe, /obj/item/slime_extract, /obj/item/swab, - )) + )) /* * Construction bag (for engineering, holds stock parts and electronics) @@ -547,7 +548,7 @@ /obj/item/stack/ore/bluespace_crystal, /obj/item/stock_parts, /obj/item/wallframe/camera, - )) + )) /obj/item/storage/bag/harpoon_quiver name = "harpoon quiver" @@ -562,9 +563,7 @@ atom_storage.max_specific_storage = WEIGHT_CLASS_TINY atom_storage.max_slots = 40 atom_storage.max_total_storage = 100 - atom_storage.set_holdable(list( - /obj/item/ammo_casing/harpoon - )) + atom_storage.set_holdable(/obj/item/ammo_casing/harpoon) /obj/item/storage/bag/harpoon_quiver/PopulateContents() for(var/i in 1 to 40) diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm index 07cba84ebd5..dfdaff500b1 100644 --- a/code/game/objects/items/storage/belt.dm +++ b/code/game/objects/items/storage/belt.dm @@ -494,9 +494,7 @@ /obj/item/storage/belt/soulstone/Initialize(mapload) . = ..() atom_storage.max_slots = 6 - atom_storage.set_holdable(list( - /obj/item/soulstone, - )) + atom_storage.set_holdable(/obj/item/soulstone) /obj/item/storage/belt/soulstone/full/PopulateContents() for(var/i in 1 to 6) @@ -517,9 +515,7 @@ /obj/item/storage/belt/champion/Initialize(mapload) . = ..() atom_storage.max_slots = 1 - atom_storage.set_holdable(list( - /obj/item/clothing/mask/luchador, - )) + atom_storage.set_holdable(/obj/item/clothing/mask/luchador) /obj/item/storage/belt/military name = "chest rig" @@ -670,9 +666,7 @@ /obj/item/storage/belt/wands/Initialize(mapload) . = ..() atom_storage.max_slots = 6 - atom_storage.set_holdable(list( - /obj/item/gun/magic/wand, - )) + atom_storage.set_holdable(/obj/item/gun/magic/wand) /obj/item/storage/belt/wands/full/PopulateContents() new /obj/item/gun/magic/wand/death(src) @@ -834,11 +828,7 @@ atom_storage.max_slots = 1 atom_storage.rustle_sound = FALSE atom_storage.max_specific_storage = WEIGHT_CLASS_BULKY - atom_storage.set_holdable( - list( - /obj/item/melee/sabre, - ) - ) + atom_storage.set_holdable(/obj/item/melee/sabre) /obj/item/storage/belt/sabre/examine(mob/user) . = ..() diff --git a/code/game/objects/items/storage/boxes/food_boxes.dm b/code/game/objects/items/storage/boxes/food_boxes.dm index 3e23d604f6d..c49fa288eb3 100644 --- a/code/game/objects/items/storage/boxes/food_boxes.dm +++ b/code/game/objects/items/storage/boxes/food_boxes.dm @@ -14,7 +14,7 @@ /obj/item/storage/box/donkpockets/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/food/donkpocket)) + atom_storage.set_holdable(/obj/item/food/donkpocket) /obj/item/storage/box/donkpockets/donkpocketspicy name = "box of spicy-flavoured donk-pockets" @@ -337,7 +337,7 @@ /obj/item/storage/box/gum/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/food/bubblegum)) + atom_storage.set_holdable(/obj/item/food/bubblegum) atom_storage.max_slots = 4 /obj/item/storage/box/gum/PopulateContents() @@ -508,7 +508,7 @@ /obj/item/storage/box/coffeepack/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/food/grown/coffee)) + atom_storage.set_holdable(/obj/item/food/grown/coffee) /obj/item/storage/box/coffeepack/PopulateContents() atom_storage.max_slots = 5 diff --git a/code/game/objects/items/storage/boxes/medical_boxes.dm b/code/game/objects/items/storage/boxes/medical_boxes.dm index c70fffc1f6e..4637b4c7d25 100644 --- a/code/game/objects/items/storage/boxes/medical_boxes.dm +++ b/code/game/objects/items/storage/boxes/medical_boxes.dm @@ -152,7 +152,7 @@ /obj/item/stack/medical/bandage, /obj/item/reagent_containers/pill, /obj/item/reagent_containers/pill/patch, - )) + )) /obj/item/storage/box/bandages/PopulateContents() for(var/i in 1 to 5) diff --git a/code/game/objects/items/storage/boxes/science_boxes.dm b/code/game/objects/items/storage/boxes/science_boxes.dm index cc8d0e7f3d0..f0654cdf024 100644 --- a/code/game/objects/items/storage/boxes/science_boxes.dm +++ b/code/game/objects/items/storage/boxes/science_boxes.dm @@ -43,7 +43,7 @@ /obj/item/storage/box/monkeycubes/Initialize(mapload) . = ..() atom_storage.max_slots = 7 - atom_storage.set_holdable(list(/obj/item/food/monkeycube)) + atom_storage.set_holdable(/obj/item/food/monkeycube) /obj/item/storage/box/monkeycubes/PopulateContents() for(var/i in 1 to 5) @@ -62,7 +62,7 @@ /obj/item/storage/box/gorillacubes/Initialize(mapload) . = ..() atom_storage.max_slots = 3 - atom_storage.set_holdable(list(/obj/item/food/monkeycube)) + atom_storage.set_holdable(/obj/item/food/monkeycube) /obj/item/storage/box/gorillacubes/PopulateContents() for(var/i in 1 to 3) diff --git a/code/game/objects/items/storage/boxes/service_boxes.dm b/code/game/objects/items/storage/boxes/service_boxes.dm index 56f59b5572e..14656f0f5f7 100644 --- a/code/game/objects/items/storage/boxes/service_boxes.dm +++ b/code/game/objects/items/storage/boxes/service_boxes.dm @@ -63,7 +63,7 @@ /obj/item/storage/box/snappops/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/toy/snappop)) + atom_storage.set_holdable(/obj/item/toy/snappop) atom_storage.max_slots = 8 /obj/item/storage/box/snappops/PopulateContents() @@ -90,7 +90,7 @@ /obj/item/storage/box/matches/Initialize(mapload) . = ..() atom_storage.max_slots = 10 - atom_storage.set_holdable(list(/obj/item/match)) + atom_storage.set_holdable(/obj/item/match) /obj/item/storage/box/matches/PopulateContents() for(var/i in 1 to 10) diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm index e1c21d1305c..a7fbe6e7452 100644 --- a/code/game/objects/items/storage/fancy.dm +++ b/code/game/objects/items/storage/fancy.dm @@ -106,7 +106,7 @@ /obj/item/storage/fancy/donut_box/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/food/donut)) + atom_storage.set_holdable(/obj/item/food/donut) /obj/item/storage/fancy/donut_box/PopulateContents() . = ..() @@ -153,7 +153,7 @@ /obj/item/storage/fancy/egg_box/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/food/egg)) + atom_storage.set_holdable(/obj/item/food/egg) /* * Fertile Egg Box @@ -186,7 +186,7 @@ /obj/item/storage/fancy/candle_box/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/flashlight/flare/candle)) + atom_storage.set_holdable(/obj/item/flashlight/flare/candle) //////////// //CIG PACK// @@ -405,7 +405,7 @@ /obj/item/storage/fancy/rollingpapers/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/rollingpaper)) + atom_storage.set_holdable(/obj/item/rollingpaper) /obj/item/storage/fancy/rollingpapers/update_overlays() . = ..() @@ -431,7 +431,7 @@ /obj/item/storage/fancy/cigarettes/cigars/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/clothing/mask/cigarette/cigar)) + atom_storage.set_holdable(/obj/item/clothing/mask/cigarette/cigar) /obj/item/storage/fancy/cigarettes/cigars/update_icon_state() . = ..() @@ -486,7 +486,7 @@ /obj/item/storage/fancy/heart_box/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/food/bonbon)) + atom_storage.set_holdable(/obj/item/food/bonbon) /obj/item/storage/fancy/nugget_box @@ -501,7 +501,7 @@ /obj/item/storage/fancy/nugget_box/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/food/nugget)) + atom_storage.set_holdable(/obj/item/food/nugget) /* * Jar of pickles @@ -523,7 +523,7 @@ /obj/item/storage/fancy/pickles_jar/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/food/pickle)) + atom_storage.set_holdable(/obj/item/food/pickle) /obj/item/storage/fancy/pickles_jar/update_icon_state() . = ..() diff --git a/code/game/objects/items/storage/garment.dm b/code/game/objects/items/storage/garment.dm index 8e812ad81af..16cf07a1439 100644 --- a/code/game/objects/items/storage/garment.dm +++ b/code/game/objects/items/storage/garment.dm @@ -45,9 +45,7 @@ atom_storage.max_total_storage = 200 atom_storage.max_slots = 15 atom_storage.insert_preposition = "in" - atom_storage.set_holdable(list( - /obj/item/clothing, - )) + atom_storage.set_holdable(/obj/item/clothing) /obj/item/storage/bag/garment/captain/PopulateContents() new /obj/item/clothing/under/rank/captain(src) diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index 35b321d892f..9c42113d263 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -114,7 +114,7 @@ atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL atom_storage.max_slots = 10 atom_storage.max_total_storage = 20 - atom_storage.set_holdable(list(/obj/item/clothing/accessory/medal)) + atom_storage.set_holdable(/obj/item/clothing/accessory/medal) /obj/item/storage/lockbox/medal/examine(mob/user) . = ..() diff --git a/code/game/objects/items/storage/medkit.dm b/code/game/objects/items/storage/medkit.dm index 23d7f2a9284..e389b990a4c 100644 --- a/code/game/objects/items/storage/medkit.dm +++ b/code/game/objects/items/storage/medkit.dm @@ -666,12 +666,16 @@ /obj/item/storage/organbox/Initialize(mapload) . = ..() - create_storage(storage_type = /datum/storage/organ_box, max_specific_storage = WEIGHT_CLASS_BULKY, max_total_storage = 21) - atom_storage.set_holdable(list( - /obj/item/organ, - /obj/item/bodypart, - /obj/item/food/icecream - )) + create_storage( + storage_type = /datum/storage/organ_box, + max_specific_storage = WEIGHT_CLASS_BULKY, + max_total_storage = 21, + canhold = list( + /obj/item/organ, + /obj/item/bodypart, + /obj/item/food/icecream, + ), + ) create_reagents(100, TRANSPARENT) START_PROCESSING(SSobj, src) @@ -766,9 +770,7 @@ atom_storage.max_slots = 8 atom_storage.screen_max_columns = 4 atom_storage.screen_max_rows = 2 - atom_storage.set_holdable(list( - /obj/item/reagent_containers/cup/tube, - )) + atom_storage.set_holdable(/obj/item/reagent_containers/cup/tube) /obj/item/storage/test_tube_rack/attack_self(mob/user) emptyStorage() diff --git a/code/game/objects/items/storage/sixpack.dm b/code/game/objects/items/storage/sixpack.dm index 8a447b4dfb1..a6e36bf0592 100644 --- a/code/game/objects/items/storage/sixpack.dm +++ b/code/game/objects/items/storage/sixpack.dm @@ -30,8 +30,8 @@ /obj/item/reagent_containers/cup/soda_cans, /obj/item/reagent_containers/cup/glass/bottle/beer, /obj/item/reagent_containers/cup/glass/bottle/ale, - /obj/item/reagent_containers/cup/glass/waterbottle - )) + /obj/item/reagent_containers/cup/glass/waterbottle, + )) /obj/item/storage/cans/sixsoda name = "soda bottle ring" diff --git a/code/game/objects/items/storage/storage.dm b/code/game/objects/items/storage/storage.dm index 501d3d2624b..cfdfef8a459 100644 --- a/code/game/objects/items/storage/storage.dm +++ b/code/game/objects/items/storage/storage.dm @@ -53,17 +53,13 @@ max_slots, max_specific_storage, max_total_storage, - numerical_stacking, - allow_quick_gather, - allow_quick_empty, - collection_mode, - attack_hand_interact, list/canhold, list/canthold, + storage_type = /datum/storage, storage_type, - ) - if(!storage_type) // If no type was passed in, default to what we already have - storage_type = src.storage_type +) + // If no type was passed in, default to what we already have + storage_type ||= src.storage_type return ..() diff --git a/code/game/objects/items/surgery_tray.dm b/code/game/objects/items/surgery_tray.dm index 958fb9fef05..0ab652f80be 100644 --- a/code/game/objects/items/surgery_tray.dm +++ b/code/game/objects/items/surgery_tray.dm @@ -1,29 +1,3 @@ -/datum/storage/surgery_tray - max_total_storage = 30 - max_specific_storage = WEIGHT_CLASS_NORMAL - max_slots = 14 - -/datum/storage/surgery_tray/New() - . = ..() - set_holdable(list( - /obj/item/autopsy_scanner, - /obj/item/blood_filter, - /obj/item/bonesetter, - /obj/item/cautery, - /obj/item/circular_saw, - /obj/item/clothing/mask/surgical, - /obj/item/clothing/suit/toggle/labcoat/hospitalgown, // NOVA EDIT ADDITION - /obj/item/hemostat, - /obj/item/razor, - /obj/item/reagent_containers/medigel, - /obj/item/retractor, - /obj/item/scalpel, - /obj/item/stack/medical/bone_gel, - /obj/item/stack/sticky_tape/surgical, - /obj/item/surgical_drapes, - /obj/item/surgicaldrill, - )) - /** * Surgery Trays * A storage object that displays tools in its contents based on tier, better tools are more visible. diff --git a/code/game/objects/items/tcg/tcg.dm b/code/game/objects/items/tcg/tcg.dm index ced4919c448..61d0dbe071d 100644 --- a/code/game/objects/items/tcg/tcg.dm +++ b/code/game/objects/items/tcg/tcg.dm @@ -414,7 +414,7 @@ GLOBAL_LIST_EMPTY(tcgcard_radial_choices) /obj/item/storage/card_binder/Initialize(mapload) . = ..() - atom_storage.set_holdable(list(/obj/item/tcgcard)) + atom_storage.set_holdable(/obj/item/tcgcard) atom_storage.max_total_storage = 120 atom_storage.max_slots = 60 diff --git a/code/game/objects/structures/secure_safe.dm b/code/game/objects/structures/secure_safe.dm index c13fe9d6085..43027090e5b 100644 --- a/code/game/objects/structures/secure_safe.dm +++ b/code/game/objects/structures/secure_safe.dm @@ -60,7 +60,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/secure_safe/caps_spare, 32) /obj/structure/secure_safe/caps_spare/Initialize(mapload) . = ..() - atom_storage.set_holdable(can_hold_list = list(/obj/item/card/id)) + atom_storage.set_holdable(/obj/item/card/id) AddComponent(/datum/component/lockable_storage, \ lock_code = SSid_access.spare_id_safe_code, \ can_hack_open = FALSE, \ diff --git a/code/game/objects/structures/toiletbong.dm b/code/game/objects/structures/toiletbong.dm index 45ce79f9c32..a0aaeeaa4bb 100644 --- a/code/game/objects/structures/toiletbong.dm +++ b/code/game/objects/structures/toiletbong.dm @@ -11,11 +11,9 @@ /obj/structure/toiletbong/Initialize(mapload) . = ..() - create_storage() + create_storage(max_total_storage = 100, max_slots = 12, canhold = /obj/item/food) atom_storage.attack_hand_interact = FALSE - atom_storage.set_holdable(list(/obj/item/food/)) - atom_storage.max_total_storage = 100 - atom_storage.max_slots = 12 + weed_overlay = mutable_appearance('icons/obj/watercloset.dmi', "toiletbong_overlay") START_PROCESSING(SSobj, src) diff --git a/code/modules/clothing/outfits/vv_outfit.dm b/code/modules/clothing/outfits/vv_outfit.dm index ec459634115..6277b5c1dd8 100644 --- a/code/modules/clothing/outfits/vv_outfit.dm +++ b/code/modules/clothing/outfits/vv_outfit.dm @@ -120,9 +120,8 @@ //Copy backpack contents if exist. var/obj/item/backpack = get_item_by_slot(ITEM_SLOT_BACK) if(istype(backpack) && backpack.atom_storage) - var/list/bp_stuff = list() + var/list/bp_stuff = backpack.atom_storage.return_inv(recursive = FALSE) var/list/typecounts = list() - backpack.atom_storage.return_inv(bp_stuff, FALSE) for(var/obj/item/backpack_item in bp_stuff) if(typecounts[backpack_item.type]) typecounts[backpack_item.type] += 1 diff --git a/code/modules/clothing/under/accessories/_accessories.dm b/code/modules/clothing/under/accessories/_accessories.dm index 8ecc3962abd..67c2768ad23 100644 --- a/code/modules/clothing/under/accessories/_accessories.dm +++ b/code/modules/clothing/under/accessories/_accessories.dm @@ -59,7 +59,7 @@ . = ..() var/obj/item/clothing/under/attached_to = loc - + if(!istype(attached_to)) return @@ -79,8 +79,10 @@ SHOULD_CALL_PARENT(TRUE) if(atom_storage) + atom_storage.close_all() attach_to.clone_storage(atom_storage) attach_to.atom_storage.set_real_location(src) + attach_to.atom_storage.rustle_sound = TRUE // it's on the suit now var/num_other_accessories = LAZYLEN(attach_to.attached_accessories) layer = FLOAT_LAYER + clamp(attach_to.max_number_of_accessories - num_other_accessories, 0, 10) @@ -118,9 +120,8 @@ /obj/item/clothing/accessory/proc/detach(obj/item/clothing/under/detach_from) SHOULD_CALL_PARENT(TRUE) - if(IS_WEAKREF_OF(src, detach_from.atom_storage?.real_location)) + if(detach_from.atom_storage?.real_location == src) // Ensure void items do not stick around - atom_storage.close_all() detach_from.atom_storage.close_all() // And clean up the storage we made QDEL_NULL(detach_from.atom_storage) diff --git a/code/modules/explorer_drone/exodrone.dm b/code/modules/explorer_drone/exodrone.dm index 5c73f5755df..5754ccc4a5e 100644 --- a/code/modules/explorer_drone/exodrone.dm +++ b/code/modules/explorer_drone/exodrone.dm @@ -70,9 +70,8 @@ GLOBAL_LIST_EMPTY(exodrone_launchers) else name_counter[name] = 1 GLOB.exodrones += src - /// Cargo storage - create_storage(max_slots = EXODRONE_CARGO_SLOTS) - atom_storage.set_holdable(cant_hold_list = GLOB.blacklisted_cargo_types) + // Cargo storage + create_storage(max_slots = EXODRONE_CARGO_SLOTS, canthold = GLOB.blacklisted_cargo_types) /obj/item/exodrone/Destroy() . = ..() diff --git a/code/modules/fishing/fishing_equipment.dm b/code/modules/fishing/fishing_equipment.dm index 2a18b1c46e8..b1e5ddc4c18 100644 --- a/code/modules/fishing/fishing_equipment.dm +++ b/code/modules/fishing/fishing_equipment.dm @@ -202,10 +202,10 @@ /obj/item/storage/toolbox/fishing/Initialize(mapload) . = ..() // Can hold fishing rod despite the size - var/static/list/exception_cache = typecacheof( + var/static/list/exception_cache = typecacheof(list( /obj/item/fishing_rod, /obj/item/fishing_line, - ) + )) atom_storage.exception_hold = exception_cache /obj/item/storage/toolbox/fishing/PopulateContents() diff --git a/code/modules/food_and_drinks/machinery/coffeemaker.dm b/code/modules/food_and_drinks/machinery/coffeemaker.dm index 5f6ef410413..36ef9a76384 100644 --- a/code/modules/food_and_drinks/machinery/coffeemaker.dm +++ b/code/modules/food_and_drinks/machinery/coffeemaker.dm @@ -489,7 +489,7 @@ /obj/item/storage/fancy/coffee_cart_rack/Initialize(mapload) . = ..() atom_storage.max_slots = 4 - atom_storage.set_holdable(list(/obj/item/coffee_cartridge)) + atom_storage.set_holdable(/obj/item/coffee_cartridge) /* * impressa coffee maker diff --git a/code/modules/food_and_drinks/machinery/griddle.dm b/code/modules/food_and_drinks/machinery/griddle.dm index 5fe48cca50a..80646a8ab09 100644 --- a/code/modules/food_and_drinks/machinery/griddle.dm +++ b/code/modules/food_and_drinks/machinery/griddle.dm @@ -151,23 +151,21 @@ default_unfasten_wrench(user, tool, time = 2 SECONDS) return ITEM_INTERACT_SUCCESS -/obj/machinery/griddle/proc/on_storage_dump(datum/source, obj/item/storage_source, mob/user) +/obj/machinery/griddle/proc/on_storage_dump(datum/source, datum/storage/storage, mob/user) SIGNAL_HANDLER - for(var/obj/item/to_dump in storage_source) - if(to_dump.loc != storage_source) - continue + for(var/obj/item/to_dump in storage.real_location) if(griddled_objects.len >= max_items) break - if(!storage_source.atom_storage.attempt_remove(to_dump, src, silent = TRUE)) + if(!storage.attempt_remove(to_dump, src, silent = TRUE)) continue to_dump.pixel_x = to_dump.base_pixel_x + rand(-5, 5) to_dump.pixel_y = to_dump.base_pixel_y + rand(-5, 5) AddToGrill(to_dump, user) - to_chat(user, span_notice("You dump out [storage_source] onto [src].")) + to_chat(user, span_notice("You dump out [storage.parent] onto [src].")) return STORAGE_DUMP_HANDLED /obj/machinery/griddle/process(seconds_per_tick) diff --git a/code/modules/mining/lavaland/tendril_loot.dm b/code/modules/mining/lavaland/tendril_loot.dm index 72d89d55b69..c84ea668630 100644 --- a/code/modules/mining/lavaland/tendril_loot.dm +++ b/code/modules/mining/lavaland/tendril_loot.dm @@ -467,8 +467,6 @@ resistance_flags = INDESTRUCTIBLE /obj/item/shared_storage/red - name = "paradox bag" - desc = "Somehow, it's in two places at once." /obj/item/shared_storage/red/Initialize(mapload) . = ..() diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 219d8e357e7..15f45694c29 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -562,9 +562,7 @@ while(i < length(processing_list)) var/atom/A = processing_list[++i] if(A.atom_storage) - var/list/item_stuff = list() - A.atom_storage.return_inv(item_stuff) - processing_list += item_stuff + processing_list += A.atom_storage.return_inv() return processing_list /// Returns a list of things that the provided mob has, including any storage-capable implants. diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index bf3c3080e5a..03e937ca8e2 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -458,11 +458,10 @@ if(!equipped_item.atom_storage?.attempt_insert(thing, src)) to_chat(src, span_warning("You can't fit [thing] into your [equipped_item.name]!")) return - var/atom/real_location = storage.real_location?.resolve() - if(!real_location.contents.len) // nothing to take out + if(!storage.real_location.contents.len) // nothing to take out to_chat(src, span_warning("There's nothing in your [equipped_item.name] to take out!")) return - var/obj/item/stored = real_location.contents[real_location.contents.len] + var/obj/item/stored = storage.real_location.contents[storage.real_location.contents.len] if(!stored || stored.on_found(src)) return stored.attack_hand(src) // take out thing from item in storage slot diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index a9747c9d34a..86370278f23 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -773,10 +773,10 @@ /mob/living/get_contents() var/list/ret = list() ret |= contents //add our contents - for(var/atom/iter_atom as anything in ret.Copy()) //iterate storage objects - iter_atom.atom_storage?.return_inv(ret) - for(var/obj/item/folder/F in ret.Copy()) //very snowflakey-ly iterate folders - ret |= F.contents + for(var/atom/iter_atom as anything in ret) //iterate storage objects + ret |= iter_atom.atom_storage?.return_inv() + for(var/obj/item/folder/folder in ret) //very snowflakey-ly iterate folders + ret |= folder.contents return ret /** @@ -1051,8 +1051,11 @@ var/mob/living/L = pulledby L.set_pull_offsets(src, pulledby.grab_state) - if(active_storage && !((active_storage.parent?.resolve() in important_recursive_contents?[RECURSIVE_CONTENTS_ACTIVE_STORAGE]) || CanReach(active_storage.parent?.resolve(),view_only = TRUE))) - active_storage.hide_contents(src) + if(active_storage) + var/storage_is_important_recurisve = (active_storage.parent in important_recursive_contents?[RECURSIVE_CONTENTS_ACTIVE_STORAGE]) + var/can_reach_active_storage = CanReach(active_storage.parent, view_only = TRUE) + if(!storage_is_important_recurisve && !can_reach_active_storage) + active_storage.hide_contents(src) if(body_position == LYING_DOWN && !buckled && prob(getBruteLoss()*200/maxHealth)) makeTrail(newloc, T, old_direction) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 4acff57f6dc..354d5564b10 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -31,11 +31,10 @@ RegisterSignal(mod.chestplate, COMSIG_ITEM_PRE_UNEQUIP, PROC_REF(on_chestplate_unequip)) /obj/item/mod/module/storage/on_uninstall(deleting = FALSE) - var/datum/storage/modstorage = mod.atom_storage atom_storage.locked = STORAGE_FULLY_LOCKED - qdel(modstorage) + QDEL_NULL(mod.atom_storage) if(!deleting) - atom_storage.remove_all(get_turf(src)) + atom_storage.remove_all(mod.drop_location()) UnregisterSignal(mod.chestplate, COMSIG_ITEM_PRE_UNEQUIP) /obj/item/mod/module/storage/proc/on_chestplate_unequip(obj/item/source, force, atom/newloc, no_move, invdrop, silent) diff --git a/code/modules/photography/photos/album.dm b/code/modules/photography/photos/album.dm index f8f8a8fb062..ddc896fe758 100644 --- a/code/modules/photography/photos/album.dm +++ b/code/modules/photography/photos/album.dm @@ -58,12 +58,17 @@ max_total_storage = 42 max_slots = 21 -/datum/storage/photo_album/New(atom/parent, max_slots, max_specific_storage, max_total_storage, numerical_stacking, allow_quick_gather, allow_quick_empty, collection_mode, attack_hand_interact) +/datum/storage/photo_album/New( + atom/parent, + max_slots, + max_specific_storage, + max_total_storage, +) . = ..() - set_holdable(list(/obj/item/photo)) + set_holdable(/obj/item/photo) /datum/storage/photo_album/proc/save_everything() - var/obj/item/storage/photo_album/album = parent.resolve() + var/obj/item/storage/photo_album/album = parent ASSERT(istype(album)) SSpersistence.photo_albums_database.set_key(album.persistence_id, album.get_picture_id_list()) diff --git a/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm b/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm index 7d8669c8618..07d7cc93ce1 100644 --- a/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm +++ b/code/modules/projectiles/guns/ballistic/bows/bow_quivers.dm @@ -15,9 +15,7 @@ atom_storage.max_specific_storage = WEIGHT_CLASS_TINY atom_storage.max_slots = 40 atom_storage.max_total_storage = 100 - atom_storage.set_holdable(list( - /obj/item/ammo_casing/arrow, - )) + atom_storage.set_holdable(/obj/item/ammo_casing/arrow) /obj/item/storage/bag/quiver/PopulateContents() . = ..() diff --git a/code/modules/projectiles/guns/energy/dueling.dm b/code/modules/projectiles/guns/energy/dueling.dm index 932117abb5b..f35769e663c 100644 --- a/code/modules/projectiles/guns/energy/dueling.dm +++ b/code/modules/projectiles/guns/energy/dueling.dm @@ -370,7 +370,7 @@ . = ..() atom_storage.max_specific_storage = WEIGHT_CLASS_SMALL atom_storage.max_slots = 2 - atom_storage.set_holdable(list(/obj/item/gun/energy/dueling)) + atom_storage.set_holdable(/obj/item/gun/energy/dueling) /obj/item/storage/lockbox/dueling/update_icon_state() if(atom_storage?.locked) diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm index df45bebaafd..2d1478a3e82 100644 --- a/code/modules/recycling/disposal/bin.dm +++ b/code/modules/recycling/disposal/bin.dm @@ -292,19 +292,17 @@ ..() ///How disposal handles getting a storage dump from a storage object -/obj/machinery/disposal/proc/on_storage_dump(datum/source, obj/item/storage_source, mob/user) +/obj/machinery/disposal/proc/on_storage_dump(datum/source, datum/storage/storage, mob/user) SIGNAL_HANDLER . = STORAGE_DUMP_HANDLED - to_chat(user, span_notice("You dump out [storage_source] into [src].")) + to_chat(user, span_notice("You dump out [storage.parent] into [src].")) - for(var/obj/item/to_dump in storage_source) - if(to_dump.loc != storage_source) - continue - if(user.active_storage != storage_source && to_dump.on_found(user)) + for(var/obj/item/to_dump in storage.real_location) + if(user.active_storage != storage && to_dump.on_found(user)) return - if(!storage_source.atom_storage.attempt_remove(to_dump, src, silent = TRUE)) + if(!storage.attempt_remove(to_dump, src, silent = TRUE)) continue to_dump.pixel_x = to_dump.base_pixel_x + rand(-5, 5) to_dump.pixel_y = to_dump.base_pixel_y + rand(-5, 5) diff --git a/modular_nova/modules/customization/modules/clothing/storage/belts.dm b/modular_nova/modules/customization/modules/clothing/storage/belts.dm index 0dc3f25f9ab..05265d030e7 100644 --- a/modular_nova/modules/customization/modules/clothing/storage/belts.dm +++ b/modular_nova/modules/customization/modules/clothing/storage/belts.dm @@ -49,10 +49,10 @@ //Overrides normal dumping code to instead dump from the pouch item inside /datum/storage/belt/crusader/dump_content_at(atom/dest_object, mob/dumping_mob) - var/atom/used_belt = parent?.resolve() + var/atom/used_belt = parent if(!used_belt) return - var/obj/item/storage/belt/storage_pouch/pouch = locate() in real_location?.resolve() + var/obj/item/storage/belt/storage_pouch/pouch = locate() in real_location if(!pouch) pouch.balloon_alert(dumping_mob, "no pouch!") return //oopsie!! If we don't have a pouch! You're fucked! diff --git a/modular_nova/modules/goofsec/code/sec_clothing_overrides.dm b/modular_nova/modules/goofsec/code/sec_clothing_overrides.dm index d7851bf6b93..a21392cd91d 100644 --- a/modular_nova/modules/goofsec/code/sec_clothing_overrides.dm +++ b/modular_nova/modules/goofsec/code/sec_clothing_overrides.dm @@ -160,7 +160,7 @@ ///Enables you to quickdraw weapons from security holsters /datum/storage/security/open_storage(datum/source, mob/user) - var/atom/resolve_parent = parent?.resolve() + var/atom/resolve_parent = parent if(!resolve_parent) return if(isobserver(user)) @@ -174,7 +174,7 @@ if(!isliving(user) || user.incapacitated()) return FALSE - var/obj/item/gun/gun_to_draw = locate() in real_location?.resolve() + var/obj/item/gun/gun_to_draw = locate() in real_location if(!gun_to_draw) return ..() resolve_parent.add_fingerprint(user)