From 8c2c72b0ed7a1fad112fc4da8a8b7de7faa5e114 Mon Sep 17 00:00:00 2001 From: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Date: Sat, 1 Jul 2023 07:36:26 -0700 Subject: [PATCH] Duiffel Spotfix (#76442) ## About The Pull Request Gives duffelbags their proper slot count They inherited this from backpacks, but I sorta just forgot about that [Creates "levels" of locked objects, uses that to make locked duffels work](https://github.com/tgstation/tgstation/pull/76442/commits/c613c00f62fa3ff03bb33737d24da9acbf2050e3) [c613c00](https://github.com/tgstation/tgstation/pull/76442/commits/c613c00f62fa3ff03bb33737d24da9acbf2050e3) Turns locked into something that holds defines, this makes life a lot easier. Requires a lot of boilerplate because of how many uses of these procs there are and all the passthrough and shit. Adds a few outfit subtypes to avoid this class of failure in future. Renames the args in a few but not all touched procs, one thing at a time Closes #76407 Closes #76430 Had the lock check in the wrong place Closes #76441 GOD I HATE TK SO MUCH Wrote half the pr without glasses so if it's weird gimme some grace yeah? ## Changelog :cl: fix: Fixes some fuck with duffelbags, them not holding enough + issues with spawning gear in them (job shit and all) /:cl: --- code/__DEFINES/storage.dm | 7 +++ code/controllers/subsystem/job.dm | 4 +- code/datums/outfit.dm | 2 +- code/datums/quirks/_quirk.dm | 2 +- code/datums/station_traits/neutral_traits.dm | 4 +- code/datums/storage/storage.dm | 12 ++-- code/datums/storage/subtypes/backpack.dm | 5 ++ code/datums/storage/subtypes/duffel_bag.dm | 1 + .../storage/subtypes/extract_inventory.dm | 2 +- code/game/gamemodes/objective.dm | 2 +- code/game/machinery/_machinery.dm | 2 +- code/game/objects/items.dm | 6 +- .../items/devices/portable_chem_mixer.dm | 5 +- code/game/objects/items/storage/backpack.dm | 28 ++++----- code/game/objects/items/storage/lockbox.dm | 23 +++++--- code/game/objects/items/storage/secure.dm | 6 +- code/modules/admin/verbs/debug.dm | 2 +- .../antagonists/changeling/changeling.dm | 2 +- code/modules/antagonists/cult/cult.dm | 2 +- code/modules/antagonists/nukeop/outfits.dm | 2 +- .../antagonists/revolution/revolution.dm | 2 +- code/modules/clothing/neck/_neck.dm | 2 +- code/modules/clothing/outfits/vr.dm | 2 +- code/modules/events/wizard/curseditems.dm | 2 +- code/modules/events/wizard/rpgloot.dm | 2 +- .../jobs/job_types/chaplain/chaplain.dm | 4 +- code/modules/mining/fulton.dm | 2 +- code/modules/mob/inventory.dm | 2 +- .../mob/living/carbon/human/_species.dm | 4 +- .../mob/living/carbon/human/inventory.dm | 45 +++++++-------- code/modules/mob/living/carbon/inventory.dm | 57 +++++++++---------- .../simple_animal/friendly/drone/inventory.dm | 24 ++++---- .../living/simple_animal/guardian/guardian.dm | 18 +++--- .../simple_animal/guardian/types/dextrous.dm | 6 +- code/modules/mob/mob.dm | 19 ++++--- code/modules/mod/modules/modules_general.dm | 6 +- .../xenobiology/crossbreeding/reproductive.dm | 2 +- code/modules/unit_tests/outfit_sanity.dm | 22 ++++++- 38 files changed, 193 insertions(+), 147 deletions(-) diff --git a/code/__DEFINES/storage.dm b/code/__DEFINES/storage.dm index 6d0860668bb..a266c86198f 100644 --- a/code/__DEFINES/storage.dm +++ b/code/__DEFINES/storage.dm @@ -15,3 +15,10 @@ #define FANCY_CONTAINER_CLOSED 0 #define FANCY_CONTAINER_OPEN 1 #define FANCY_CONTAINER_ALWAYS_OPEN 2 + +// Defines for levels of storage locking +// Also used fort the force param of can_insert +// Higher values are "more" locked then lower ones +#define STORAGE_NOT_LOCKED 0 +#define STORAGE_SOFT_LOCKED 1 +#define STORAGE_FULLY_LOCKED 2 diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 67dc3f81ed7..19bd2e856a6 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -1035,7 +1035,7 @@ SUBSYSTEM_DEF(job) LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS ) - var/where = new_captain.equip_in_one_of_slots(paper, slots, FALSE) || "at your feet" + var/where = new_captain.equip_in_one_of_slots(paper, slots, FALSE, indirect_action = TRUE) || "at your feet" if(acting_captain) to_chat(new_captain, span_notice("Due to your position in the chain of command, you have been promoted to Acting Captain. You can find in important note about this [where].")) @@ -1106,7 +1106,7 @@ SUBSYSTEM_DEF(job) if(is_banned_from(player.ckey, possible_job.title)) JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_BANNED, possible_job.title)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") return JOB_UNAVAILABLE_BANNED - + // Check for character age if(possible_job.required_character_age > player.client.prefs.read_preference(/datum/preference/numeric/age) && possible_job.required_character_age != null) JobDebug("[debug_prefix] Error: [get_job_unavailable_error_message(JOB_UNAVAILABLE_AGE)], Player: [player][add_job_to_log ? ", Job: [possible_job]" : ""]") diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm index e766131a8aa..696c4c2957d 100644 --- a/code/datums/outfit.dm +++ b/code/datums/outfit.dm @@ -153,7 +153,7 @@ return #define EQUIP_OUTFIT_ITEM(item_path, slot_name) if(##item_path) { \ - user.equip_to_slot_or_del(SSwardrobe.provide_type(##item_path, user), ##slot_name, TRUE); \ + user.equip_to_slot_or_del(SSwardrobe.provide_type(##item_path, user), ##slot_name, TRUE, indirect_action = TRUE); \ var/obj/item/outfit_item = user.get_item_by_slot(##slot_name); \ if (outfit_item && outfit_item.type == ##item_path) { \ outfit_item.on_outfit_equip(user, visualsOnly, ##slot_name); \ diff --git a/code/datums/quirks/_quirk.dm b/code/datums/quirks/_quirk.dm index 8e27619f9ba..7b89e7c8222 100644 --- a/code/datums/quirks/_quirk.dm +++ b/code/datums/quirks/_quirk.dm @@ -173,7 +173,7 @@ var/mob/living/carbon/human/human_holder = quirk_holder - var/where = human_holder.equip_in_one_of_slots(quirk_item, valid_slots, qdel_on_fail = FALSE) || default_location + var/where = human_holder.equip_in_one_of_slots(quirk_item, valid_slots, qdel_on_fail = FALSE, indirect_action = TRUE) || default_location if(where == LOCATION_BACKPACK) open_backpack = TRUE diff --git a/code/datums/station_traits/neutral_traits.dm b/code/datums/station_traits/neutral_traits.dm index 88407dd45ab..73d9a4e6056 100644 --- a/code/datums/station_traits/neutral_traits.dm +++ b/code/datums/station_traits/neutral_traits.dm @@ -271,7 +271,7 @@ )) hat = new hat(spawned_mob) if(!spawned_mob.equip_to_slot_if_possible(hat, ITEM_SLOT_HEAD, disable_warning = TRUE)) - spawned_mob.equip_to_slot_or_del(hat, ITEM_SLOT_BACKPACK) + spawned_mob.equip_to_slot_or_del(hat, ITEM_SLOT_BACKPACK, indirect_action = TRUE) var/obj/item/toy = pick_weight(list( /obj/item/reagent_containers/spray/chemsprayer/party = 4, /obj/item/toy/balloon = 2, @@ -283,7 +283,7 @@ if(istype(toy, /obj/item/toy/balloon)) spawned_mob.equip_to_slot_or_del(toy, ITEM_SLOT_HANDS) //Balloons do not fit inside of backpacks. else - spawned_mob.equip_to_slot_or_del(toy, ITEM_SLOT_BACKPACK) + spawned_mob.equip_to_slot_or_del(toy, ITEM_SLOT_BACKPACK, indirect_action = TRUE) if(birthday_person_name) //Anyone who joins after the annoucement gets one of these. var/obj/item/birthday_invite/birthday_invite = new(spawned_mob) birthday_invite.setup_card(birthday_person_name) diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 9d85effbd8a..bc2c9e017ac 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -33,7 +33,7 @@ /// list of all the mobs currently viewing the contents var/list/is_using = list() - var/locked = FALSE + var/locked = STORAGE_NOT_LOCKED /// whether or not we should open when clicked var/attack_hand_interact = TRUE /// whether or not we allow storage objects of the same size inside @@ -310,9 +310,9 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) * * @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 + * @param 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 = FALSE) +/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 @@ -327,7 +327,7 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) if(!isitem(to_insert)) return FALSE - if(locked && !force) + if(locked > force) return FALSE if((to_insert == resolve_parent) || (to_insert == real_location)) @@ -406,9 +406,9 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) * @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 + * @param 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 = FALSE) +/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 diff --git a/code/datums/storage/subtypes/backpack.dm b/code/datums/storage/subtypes/backpack.dm index 308abf1eb69..a6b3e1477dd 100644 --- a/code/datums/storage/subtypes/backpack.dm +++ b/code/datums/storage/subtypes/backpack.dm @@ -1,3 +1,8 @@ /datum/storage/backpack max_total_storage = 21 max_slots = 21 + +/datum/storage/backpack/santabag + max_total_storage = 60 + max_slots = 21 + max_specific_storage = WEIGHT_CLASS_NORMAL diff --git a/code/datums/storage/subtypes/duffel_bag.dm b/code/datums/storage/subtypes/duffel_bag.dm index 54caa43c761..95067651e08 100644 --- a/code/datums/storage/subtypes/duffel_bag.dm +++ b/code/datums/storage/subtypes/duffel_bag.dm @@ -1,5 +1,6 @@ /datum/storage/duffel max_total_storage = 30 + max_slots = 21 // Syndi bags get some FUN extras // You can fit any 3 bulky objects (assuming they're in the whitelist) diff --git a/code/datums/storage/subtypes/extract_inventory.dm b/code/datums/storage/subtypes/extract_inventory.dm index 4aefd6781b7..8c571dbda1a 100644 --- a/code/datums/storage/subtypes/extract_inventory.dm +++ b/code/datums/storage/subtypes/extract_inventory.dm @@ -4,7 +4,7 @@ insert_preposition = "in" attack_hand_interact = FALSE quickdraw = FALSE - locked = TRUE + locked = STORAGE_FULLY_LOCKED rustle_sound = FALSE silent = TRUE diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 1963803c438..22a5667b458 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -170,7 +170,7 @@ GLOBAL_LIST(admin_objective_list) //Prefilled admin assignable objective list var/list/slots = list("backpack" = ITEM_SLOT_BACKPACK) for(var/obj/equipment_path as anything in special_equipment) var/obj/equipment_object = new equipment_path - if(!receiver_current.equip_in_one_of_slots(equipment_object, slots)) + if(!receiver_current.equip_in_one_of_slots(equipment_object, slots, indirect_action = TRUE)) LAZYINITLIST(receiver.failed_special_equipment) receiver.failed_special_equipment += equipment_path receiver.try_give_equipment_fallback() diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index a5b700df559..6d2832f17dd 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -1005,7 +1005,7 @@ else physical_part = primary_part_base - replacer_tool.atom_storage.attempt_insert(physical_part, user, TRUE) + replacer_tool.atom_storage.attempt_insert(physical_part, user, TRUE, force = STORAGE_SOFT_LOCKED) to_chat(user, span_notice("[capitalize(physical_part.name)] replaced with [secondary_part_name].")) shouldplaysound = TRUE //Only play the sound when parts are actually replaced! break diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index a6436ba16a9..04f04e83979 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -704,12 +704,14 @@ * * disable_warning to TRUE if you wish it to not give you text outputs. * * slot is the slot we are trying to equip to * * bypass_equip_delay_self for whether we want to bypass the equip delay + * * ignore_equipped ignores any already equipped items in that slot + * * indirect_action allows inserting into "soft locked" bags, things that can be easily opened by the owner */ -/obj/item/proc/mob_can_equip(mob/living/M, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE) +/obj/item/proc/mob_can_equip(mob/living/M, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE, indirect_action = FALSE) if(!M) return FALSE - return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self, ignore_equipped) + return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self, ignore_equipped, indirect_action = indirect_action) /obj/item/verb/verb_pickup() set src in oview(1) diff --git a/code/game/objects/items/devices/portable_chem_mixer.dm b/code/game/objects/items/devices/portable_chem_mixer.dm index e4631936693..18458f75697 100644 --- a/code/game/objects/items/devices/portable_chem_mixer.dm +++ b/code/game/objects/items/devices/portable_chem_mixer.dm @@ -89,7 +89,10 @@ update_appearance() /obj/item/storage/portable_chem_mixer/CtrlClick(mob/living/user) - atom_storage.locked = !atom_storage.locked + if(atom_storage.locked) + atom_storage.locked = STORAGE_NOT_LOCKED + else + atom_storage.locked = STORAGE_FULLY_LOCKED if (!atom_storage.locked) update_contents() if (atom_storage.locked) diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index 301f21c5129..3639c01aec3 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -78,16 +78,12 @@ icon_state = "giftbag0" inhand_icon_state = "giftbag" w_class = WEIGHT_CLASS_BULKY + storage_type = /datum/storage/backpack/santabag /obj/item/storage/backpack/santabag/Initialize(mapload) . = ..() regenerate_presents() -/obj/item/storage/backpack/santabag/Initialize(mapload) - . = ..() - atom_storage.max_specific_storage = WEIGHT_CLASS_NORMAL - atom_storage.max_total_storage = 60 - /obj/item/storage/backpack/santabag/suicide_act(mob/living/user) user.visible_message(span_suicide("[user] places [src] over [user.p_their()] head and pulls it tight! It looks like [user.p_they()] [user.p_are()]n't in the Christmas spirit...")) return OXYLOSS @@ -101,7 +97,7 @@ if(user.mind && HAS_TRAIT(user.mind, TRAIT_CANNOT_OPEN_PRESENTS)) var/turf/floor = get_turf(src) var/obj/item/thing = new /obj/item/a_gift/anything(floor) - if(!atom_storage.attempt_insert(thing, user, override = TRUE)) + if(!atom_storage.attempt_insert(thing, user, override = TRUE, force = STORAGE_SOFT_LOCKED)) qdel(thing) @@ -395,8 +391,10 @@ inhand_icon_state = "duffel" actions_types = list(/datum/action/item_action/zipper) storage_type = /datum/storage/duffel + // How much to slow you down if your bag isn't zipped up + var/zip_slowdown = 1 /// If this bag is zipped (contents hidden) up or not - /// Starts enabled so people need to figure it out to use the thing + /// Starts enabled so you're forced to interact with it to "get" it var/zipped_up = TRUE /obj/item/storage/backpack/duffelbag/Initialize(mapload) @@ -408,6 +406,8 @@ desc = "[initial(desc)]
[zipped_up ? "It's zipped up, preventing you from accessing its contents." : "It's unzipped, and harder to move in."]" /obj/item/storage/backpack/duffelbag/attack_self(mob/user, modifiers) + if(loc != user) // God fuck TK + return ..() if(zipped_up) return attack_hand(user, modifiers) else @@ -439,9 +439,9 @@ // Vis versa /obj/item/storage/backpack/duffelbag/attack_hand_secondary(mob/user, list/modifiers) + if(loc != user) + return ..() if(zipped_up) - if(loc != user) - return ..() return SECONDARY_ATTACK_CALL_NORMAL balloon_alert(user, "zipping...") @@ -462,13 +462,13 @@ zipped_up = new_zip SEND_SIGNAL(src, COMSIG_DUFFEL_ZIP_CHANGE, new_zip) if(zipped_up) - slowdown = 0 - atom_storage.locked = TRUE + slowdown = initial(slowdown) + atom_storage.locked = STORAGE_SOFT_LOCKED atom_storage.display_contents = FALSE atom_storage.close_all() else - slowdown = 1 - atom_storage.locked = FALSE + slowdown = zip_slowdown + atom_storage.locked = STORAGE_NOT_LOCKED atom_storage.display_contents = TRUE if(isliving(loc)) @@ -483,7 +483,7 @@ then it might have negative effects on the bag..." icon_state = "duffel-curse" inhand_icon_state = "duffel-curse" - slowdown = 2 + zip_slowdown = 2 max_integrity = 100 /obj/item/storage/backpack/duffelbag/cursed/Initialize(mapload) diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm index 59eb86137a8..ca98ac360f1 100644 --- a/code/game/objects/items/storage/lockbox.dm +++ b/code/game/objects/items/storage/lockbox.dm @@ -30,7 +30,10 @@ balloon_alert(user, "broken!") return if(allowed(user)) - atom_storage.locked = !locked + if(atom_storage.locked) + atom_storage.locked = STORAGE_NOT_LOCKED + else + atom_storage.locked = STORAGE_FULLY_LOCKED locked = atom_storage.locked if(locked) icon_state = icon_locked @@ -52,7 +55,7 @@ /obj/item/storage/lockbox/emag_act(mob/user) if(!broken) broken = TRUE - atom_storage.locked = FALSE + atom_storage.locked = STORAGE_NOT_LOCKED icon_state = src.icon_broken if(user) visible_message(span_warning("\The [src] is broken by [user] with an electromagnetic card!")) @@ -116,11 +119,12 @@ . += span_notice("Alt-click to [open ? "close":"open"] it.") /obj/item/storage/lockbox/medal/AltClick(mob/user) - if(user.can_perform_action(src)) - if(!atom_storage.locked) - open = (open ? FALSE : TRUE) - update_appearance() - ..() + if(!user.can_perform_action(src)) + return + if(!atom_storage.locked) + open = (open ? FALSE : TRUE) + update_appearance() + ..() /obj/item/storage/lockbox/medal/PopulateContents() new /obj/item/clothing/accessory/medal/gold/captain(src) @@ -244,7 +248,10 @@ balloon_alert(user, "incorrect bank account!") return - atom_storage.locked = !privacy_lock + if(privacy_lock) + atom_storage.locked = STORAGE_NOT_LOCKED + else + atom_storage.locked = STORAGE_FULLY_LOCKED privacy_lock = atom_storage.locked user.visible_message(span_notice("[user] [privacy_lock ? "" : "un"]locks [src]'s privacy lock."), span_notice("You [privacy_lock ? "" : "un"]lock [src]'s privacy lock.")) diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm index b67e7086344..46eb8356c79 100644 --- a/code/game/objects/items/storage/secure.dm +++ b/code/game/objects/items/storage/secure.dm @@ -96,14 +96,14 @@ lock_code = entered_code lock_set = TRUE else if ((entered_code == lock_code) && lock_set) - atom_storage.locked = FALSE + atom_storage.locked = STORAGE_NOT_LOCKED update_appearance() entered_code = null else entered_code = "ERROR" else if (href_list["type"] == "R") - atom_storage.locked = TRUE + atom_storage.locked = STORAGE_FULLY_LOCKED update_appearance() entered_code = null atom_storage.hide_contents(usr) @@ -231,7 +231,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/item/storage/secure/safe/caps_spare, 32) atom_storage.set_holdable(can_hold_list = list(/obj/item/card/id)) lock_code = SSid_access.spare_id_safe_code lock_set = TRUE - atom_storage.locked = TRUE + atom_storage.locked = STORAGE_FULLY_LOCKED update_appearance() /obj/item/storage/secure/safe/caps_spare/PopulateContents() diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index b68db5cdeba..e7cbf88725f 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -177,7 +177,7 @@ id.forceMove(W) W.update_icon() else - H.equip_to_slot(id,ITEM_SLOT_ID) + H.equip_to_slot(id, ITEM_SLOT_ID) else tgui_alert(usr,"Invalid mob") diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 489a939b586..355f33f6410 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -848,7 +848,7 @@ flesh_id.hud_icon = chosen_profile.id_icon if(equip) - user.equip_to_slot_or_del(new_flesh_item, slot2slot[slot]) + user.equip_to_slot_or_del(new_flesh_item, slot2slot[slot], indirect_action = TRUE) if(!QDELETED(new_flesh_item)) ADD_TRAIT(new_flesh_item, TRAIT_NODROP, CHANGELING_TRAIT) diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm index 74b0aff0025..affc05f6a4e 100644 --- a/code/modules/antagonists/cult/cult.dm +++ b/code/modules/antagonists/cult/cult.dm @@ -119,7 +119,7 @@ var/T = new item_path(mob) var/item_name = initial(item_path.name) - var/where = mob.equip_in_one_of_slots(T, slots) + var/where = mob.equip_in_one_of_slots(T, slots, indirect_action = TRUE) if(!where) to_chat(mob, span_userdanger("Unfortunately, you weren't able to get a [item_name]. This is very bad and you should adminhelp immediately (press F1).")) return FALSE diff --git a/code/modules/antagonists/nukeop/outfits.dm b/code/modules/antagonists/nukeop/outfits.dm index 4b8560dc918..45acac83d24 100644 --- a/code/modules/antagonists/nukeop/outfits.dm +++ b/code/modules/antagonists/nukeop/outfits.dm @@ -40,7 +40,7 @@ if(ispath(uplink_type, /obj/item/uplink/nuclear) || tc) // /obj/item/uplink/nuclear understands 0 tc var/obj/item/uplink = new uplink_type(nukie, nukie.key, tc) - nukie.equip_to_slot_or_del(uplink, ITEM_SLOT_BACKPACK) + nukie.equip_to_slot_or_del(uplink, ITEM_SLOT_BACKPACK, indirect_action = TRUE) var/obj/item/implant/weapons_auth/weapons_implant = new/obj/item/implant/weapons_auth(nukie) weapons_implant.implant(nukie) diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm index 6a62183e6af..85a79769f3f 100644 --- a/code/modules/antagonists/revolution/revolution.dm +++ b/code/modules/antagonists/revolution/revolution.dm @@ -397,7 +397,7 @@ "left pocket" = ITEM_SLOT_LPOCKET, "right pocket" = ITEM_SLOT_RPOCKET ) - var/where = C.equip_in_one_of_slots(T, slots) + var/where = C.equip_in_one_of_slots(T, slots, indirect_action = TRUE) if (!where) to_chat(C, "The Syndicate were unfortunately unable to get you a flash.") else diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm index d8abfe4b1bd..b33e1311eae 100644 --- a/code/modules/clothing/neck/_neck.dm +++ b/code/modules/clothing/neck/_neck.dm @@ -315,7 +315,7 @@ fire = 50 acid = 40 -/obj/item/clothing/neck/petcollar/mob_can_equip(mob/M, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE) +/obj/item/clothing/neck/petcollar/mob_can_equip(mob/M, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE, indirect_action = FALSE) if(!ismonkey(M)) return FALSE return ..() diff --git a/code/modules/clothing/outfits/vr.dm b/code/modules/clothing/outfits/vr.dm index 5c3b38fb63e..fb618cd831b 100644 --- a/code/modules/clothing/outfits/vr.dm +++ b/code/modules/clothing/outfits/vr.dm @@ -27,7 +27,7 @@ /datum/outfit/vr/syndicate/post_equip(mob/living/carbon/human/H) . = ..() var/obj/item/uplink/U = new /obj/item/uplink/nuclear_restricted(H, H.key, 80) - H.equip_to_slot_or_del(U, ITEM_SLOT_BACKPACK) + H.equip_to_slot_or_del(U, ITEM_SLOT_BACKPACK, indirect_action = TRUE) var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(H) W.implant(H) var/obj/item/implant/explosive/E = new/obj/item/implant/explosive(H) diff --git a/code/modules/events/wizard/curseditems.dm b/code/modules/events/wizard/curseditems.dm index cc63c15cda5..970ce67d008 100644 --- a/code/modules/events/wizard/curseditems.dm +++ b/code/modules/events/wizard/curseditems.dm @@ -50,7 +50,7 @@ var/obj/item/J = loadout[i] var/obj/item/I = new J //dumb but required because of byond throwing a fit anytime new gets too close to a list H.dropItemToGround(H.get_item_by_slot(i), TRUE) - H.equip_to_slot_or_del(I, i) + H.equip_to_slot_or_del(I, i, indirect_action = TRUE) ADD_TRAIT(I, TRAIT_NODROP, CURSED_ITEM_TRAIT(I)) I.item_flags |= DROPDEL I.name = "cursed " + I.name diff --git a/code/modules/events/wizard/rpgloot.dm b/code/modules/events/wizard/rpgloot.dm index 79b0462d516..9e2f96c63c6 100644 --- a/code/modules/events/wizard/rpgloot.dm +++ b/code/modules/events/wizard/rpgloot.dm @@ -96,7 +96,7 @@ GLOBAL_DATUM(rpgloot_controller, /datum/rpgloot_controller) var/datum/storage/storage_component = storage_item.atom_storage if(prob(upgrade_scroll_chance) && storage_item.contents.len < storage_component.max_slots && !storage_item.invisibility) var/obj/item/upgradescroll/scroll = new(get_turf(storage_item)) - storage_item.atom_storage?.attempt_insert(scroll, override = TRUE) + storage_item.atom_storage?.attempt_insert(scroll, override = TRUE, force = STORAGE_SOFT_LOCKED) upgrade_scroll_chance = max(0,upgrade_scroll_chance-100) if(isturf(scroll.loc)) qdel(scroll) diff --git a/code/modules/jobs/job_types/chaplain/chaplain.dm b/code/modules/jobs/job_types/chaplain/chaplain.dm index 4714bf589d4..19e166ee8e5 100644 --- a/code/modules/jobs/job_types/chaplain/chaplain.dm +++ b/code/modules/jobs/job_types/chaplain/chaplain.dm @@ -55,7 +55,7 @@ if(GLOB.bible_inhand_icon_state) holy_bible.inhand_icon_state = GLOB.bible_inhand_icon_state to_chat(human_spawned, span_boldnotice("There is already an established religion onboard the station. You are an acolyte of [GLOB.deity]. Defer to the Chaplain.")) - human_spawned.equip_to_slot_or_del(holy_bible, ITEM_SLOT_BACKPACK) + human_spawned.equip_to_slot_or_del(holy_bible, ITEM_SLOT_BACKPACK, indirect_action = TRUE) var/nrt = GLOB.holy_weapon_type || /obj/item/nullrod var/obj/item/nullrod/nullrod = new nrt(human_spawned) human_spawned.put_in_hands(nullrod) @@ -104,7 +104,7 @@ GLOB.bible_name = new_bible GLOB.deity = holy_bible.deity_name - human_spawned.equip_to_slot_or_del(holy_bible, ITEM_SLOT_BACKPACK) + human_spawned.equip_to_slot_or_del(holy_bible, ITEM_SLOT_BACKPACK, indirect_action = TRUE) SSblackbox.record_feedback("text", "religion_name", 1, "[new_religion]", 1) SSblackbox.record_feedback("text", "religion_deity", 1, "[new_deity]", 1) diff --git a/code/modules/mining/fulton.dm b/code/modules/mining/fulton.dm index a0920e0dba3..f679aa52c15 100644 --- a/code/modules/mining/fulton.dm +++ b/code/modules/mining/fulton.dm @@ -63,7 +63,7 @@ GLOBAL_LIST_EMPTY(total_extraction_beacons) if(do_after(user,50,target=A)) to_chat(user, span_notice("You attach the pack to [A] and activate it.")) if(loc == user) - user.back?.atom_storage?.attempt_insert(src, user) + user.back?.atom_storage?.attempt_insert(src, user, force = STORAGE_SOFT_LOCKED) uses_left-- if(uses_left <= 0) user.transferItemToLoc(src, A, TRUE) diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 6bd20d9a7e7..ad36ac94596 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -140,7 +140,7 @@ //Returns if a certain item can be equipped to a certain slot. // Currently invalid for two-handed items - call obj/item/mob_can_equip() instead. -/mob/proc/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE) +/mob/proc/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE, indirect_action = FALSE) return FALSE /mob/proc/can_put_in_hand(I, hand_index) diff --git a/code/modules/mob/living/carbon/human/_species.dm b/code/modules/mob/living/carbon/human/_species.dm index 790aa6bdfea..92554e04575 100644 --- a/code/modules/mob/living/carbon/human/_species.dm +++ b/code/modules/mob/living/carbon/human/_species.dm @@ -818,7 +818,7 @@ GLOBAL_LIST_EMPTY(features_by_species) /datum/species/proc/spec_death(gibbed, mob/living/carbon/human/H) return -/datum/species/proc/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE) +/datum/species/proc/can_equip(obj/item/I, slot, disable_warning, mob/living/carbon/human/H, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE, indirect_action = FALSE) if(no_equip_flags & slot) if(!I.species_exception || !is_type_in_list(src, I.species_exception)) return FALSE @@ -963,7 +963,7 @@ GLOBAL_LIST_EMPTY(features_by_species) return FALSE return TRUE if(ITEM_SLOT_BACKPACK) - if(H.back && H.back.atom_storage?.can_insert(I, H, messages = TRUE)) + if(H.back && H.back.atom_storage?.can_insert(I, H, messages = TRUE, force = indirect_action ? STORAGE_SOFT_LOCKED : STORAGE_NOT_LOCKED)) return TRUE return FALSE return FALSE //Unsupported slot diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm index 6686725f65b..665d9683d53 100644 --- a/code/modules/mob/living/carbon/human/inventory.dm +++ b/code/modules/mob/living/carbon/human/inventory.dm @@ -1,8 +1,8 @@ -/mob/living/carbon/human/can_equip(obj/item/equip_target, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE) +/mob/living/carbon/human/can_equip(obj/item/equip_target, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE, indirect_action = FALSE) if(SEND_SIGNAL(src, COMSIG_HUMAN_EQUIPPING_ITEM, equip_target, slot) == COMPONENT_BLOCK_EQUIP) return FALSE - return dna.species.can_equip(equip_target, slot, disable_warning, src, bypass_equip_delay_self, ignore_equipped) + return dna.species.can_equip(equip_target, slot, disable_warning, src, bypass_equip_delay_self, ignore_equipped, indirect_action) /mob/living/carbon/human/get_item_by_slot(slot_id) switch(slot_id) @@ -142,7 +142,7 @@ //This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() // Initial is used to indicate whether or not this is the initial equipment (job datums etc) or just a player doing it -/mob/living/carbon/human/equip_to_slot(obj/item/I, slot, initial = FALSE, redraw_mob = FALSE) +/mob/living/carbon/human/equip_to_slot(obj/item/equipping, slot, initial = FALSE, redraw_mob = FALSE, indirect_action = FALSE) if(!..()) //a check failed or the item has already found its slot return @@ -151,48 +151,47 @@ if(ITEM_SLOT_BELT) if(belt) return - belt = I + belt = equipping update_worn_belt() if(ITEM_SLOT_ID) if(wear_id) return - wear_id = I + wear_id = equipping sec_hud_set_ID() update_worn_id() if(ITEM_SLOT_EARS) if(ears) return - ears = I + ears = equipping update_inv_ears() if(ITEM_SLOT_EYES) if(glasses) return - glasses = I - var/obj/item/clothing/glasses/G = I - if(G.glass_colour_type) - update_glasses_color(G, 1) - if(G.tint) + glasses = equipping + if(glasses.glass_colour_type) + update_glasses_color(glasses, 1) + if(glasses.tint) update_tint() - if(G.vision_flags || G.invis_override || G.invis_view || !isnull(G.lighting_cutoff)) + if(glasses.vision_flags || glasses.invis_override || glasses.invis_view || !isnull(glasses.lighting_cutoff)) update_sight() update_worn_glasses() if(ITEM_SLOT_GLOVES) if(gloves) return - gloves = I + gloves = equipping update_worn_gloves() if(ITEM_SLOT_FEET) if(shoes) return - shoes = I + shoes = equipping update_worn_shoes() if(ITEM_SLOT_OCLOTHING) if(wear_suit) return - wear_suit = I + wear_suit = equipping - if(I.flags_inv & HIDEJUMPSUIT) + if(equipping.flags_inv & HIDEJUMPSUIT) update_worn_undersuit() if(wear_suit.breakouttime) //when equipping a straightjacket ADD_TRAIT(src, TRAIT_RESTRAINED, SUIT_TRAIT) @@ -202,30 +201,30 @@ if(ITEM_SLOT_ICLOTHING) if(w_uniform) return - w_uniform = I + w_uniform = equipping update_suit_sensors() update_worn_undersuit() if(ITEM_SLOT_LPOCKET) - l_store = I + l_store = equipping update_pockets() if(ITEM_SLOT_RPOCKET) - r_store = I + r_store = equipping update_pockets() if(ITEM_SLOT_SUITSTORE) if(s_store) return - s_store = I + s_store = equipping update_suit_storage() else to_chat(src, span_danger("You are trying to equip this item to an unsupported inventory slot. Report this to a coder!")) //Item is handled and in slot, valid to call callback, for this proc should always be true if(!not_handled) - has_equipped(I, slot, initial) + has_equipped(equipping, slot, initial) // Send a signal for when we equip an item that used to cover our feet/shoes. Used for bloody feet - if((I.body_parts_covered & FEET) || (I.flags_inv | I.transparent_protection) & HIDESHOES) - SEND_SIGNAL(src, COMSIG_CARBON_EQUIP_SHOECOVER, I, slot, initial, redraw_mob) + if(equipping.body_parts_covered & FEET || (equipping.flags_inv | equipping.transparent_protection) & HIDESHOES) + SEND_SIGNAL(src, COMSIG_CARBON_EQUIP_SHOECOVER, equipping, slot, initial, redraw_mob) return not_handled //For future deeper overrides diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index 08b752f9804..fa6e754dceb 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -49,74 +49,73 @@ legcuffed, ) -/mob/living/carbon/proc/equip_in_one_of_slots(obj/item/I, list/slots, qdel_on_fail = 1) +/mob/living/carbon/proc/equip_in_one_of_slots(obj/item/equipping, list/slots, qdel_on_fail = TRUE, indirect_action = FALSE) for(var/slot in slots) - if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0, disable_warning = TRUE)) + if(equip_to_slot_if_possible(equipping, slots[slot], disable_warning = TRUE, indirect_action = indirect_action)) return slot if(qdel_on_fail) - qdel(I) + qdel(equipping) return null //This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible() -/mob/living/carbon/equip_to_slot(obj/item/I, slot, initial = FALSE, redraw_mob = FALSE) +/mob/living/carbon/equip_to_slot(obj/item/equipping, slot, initial = FALSE, redraw_mob = FALSE, indirect_action = FALSE) if(!slot) return - if(!istype(I)) + if(!istype(equipping)) return - var/index = get_held_index_of_item(I) + var/index = get_held_index_of_item(equipping) if(index) held_items[index] = null - if(I.pulledby) - I.pulledby.stop_pulling() + if(equipping.pulledby) + equipping.pulledby.stop_pulling() - I.screen_loc = null + equipping.screen_loc = null if(client) - client.screen -= I + client.screen -= equipping if(observers?.len) - for(var/M in observers) - var/mob/dead/observe = M + for(var/mob/dead/observe as anything in observers) if(observe.client) - observe.client.screen -= I - I.forceMove(src) - SET_PLANE_EXPLICIT(I, ABOVE_HUD_PLANE, src) - I.appearance_flags |= NO_CLIENT_COLOR + observe.client.screen -= equipping + equipping.forceMove(src) + SET_PLANE_EXPLICIT(equipping, ABOVE_HUD_PLANE, src) + equipping.appearance_flags |= NO_CLIENT_COLOR var/not_handled = FALSE switch(slot) if(ITEM_SLOT_BACK) if(back) return - back = I + back = equipping update_worn_back() if(ITEM_SLOT_MASK) if(wear_mask) return - wear_mask = I - wear_mask_update(I, toggle_off = 0) + wear_mask = equipping + wear_mask_update(equipping, toggle_off = 0) if(ITEM_SLOT_HEAD) if(head) return - head = I - SEND_SIGNAL(src, COMSIG_CARBON_EQUIP_HAT, I) - head_update(I) + head = equipping + SEND_SIGNAL(src, COMSIG_CARBON_EQUIP_HAT, equipping) + head_update(equipping) if(ITEM_SLOT_NECK) if(wear_neck) return - wear_neck = I - update_worn_neck(I) + wear_neck = equipping + update_worn_neck(equipping) if(ITEM_SLOT_HANDCUFFED) - set_handcuffed(I) + set_handcuffed(equipping) update_handcuffed() if(ITEM_SLOT_LEGCUFFED) - legcuffed = I + legcuffed = equipping update_worn_legcuffs() if(ITEM_SLOT_HANDS) - put_in_hands(I) + put_in_hands(equipping) update_held_items() if(ITEM_SLOT_BACKPACK) - if(!back || !back.atom_storage?.attempt_insert(I, src, override = TRUE)) + if(!back || !back.atom_storage?.attempt_insert(equipping, src, override = TRUE, force = indirect_action ? STORAGE_SOFT_LOCKED : STORAGE_NOT_LOCKED)) not_handled = TRUE else not_handled = TRUE @@ -125,7 +124,7 @@ //We cannot call it for items that have not been handled as they are not yet correctly //in a slot (handled further down inheritance chain, probably living/carbon/human/equip_to_slot if(!not_handled) - has_equipped(I, slot, initial) + has_equipped(equipping, slot, initial) return not_handled diff --git a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm index 27d9a9f4dc9..c8d82f69957 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm @@ -19,7 +19,7 @@ return FALSE -/mob/living/simple_animal/drone/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE) +/mob/living/simple_animal/drone/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE, indirect_action = FALSE) switch(slot) if(ITEM_SLOT_HEAD) if(head) @@ -50,37 +50,37 @@ return ITEM_SLOT_HEAD return ..() -/mob/living/simple_animal/drone/equip_to_slot(obj/item/I, slot) +/mob/living/simple_animal/drone/equip_to_slot(obj/item/equipping, slot, initial = FALSE, redraw_mob = FALSE, indirect_action = FALSE) if(!slot) return - if(!istype(I)) + if(!istype(equipping)) return - var/index = get_held_index_of_item(I) + var/index = get_held_index_of_item(equipping) if(index) held_items[index] = null update_held_items() - if(I.pulledby) - I.pulledby.stop_pulling() + if(equipping.pulledby) + equipping.pulledby.stop_pulling() - I.screen_loc = null // will get moved if inventory is visible - I.forceMove(src) - SET_PLANE_EXPLICIT(I, ABOVE_HUD_PLANE, src) + equipping.screen_loc = null // will get moved if inventory is visible + equipping.forceMove(src) + SET_PLANE_EXPLICIT(equipping, ABOVE_HUD_PLANE, src) switch(slot) if(ITEM_SLOT_HEAD) - head = I + head = equipping update_worn_head() if(ITEM_SLOT_DEX_STORAGE) - internal_storage = I + internal_storage = equipping update_inv_internal_storage() else to_chat(src, span_danger("You are trying to equip this item to an unsupported inventory slot. Report this to a coder!")) return //Call back for item being equipped to drone - I.equipped(src, slot) + equipping.equipped(src, slot) /mob/living/simple_animal/drone/getBackSlot() return ITEM_SLOT_DEX_STORAGE diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index ba9ba705fa0..866d725202f 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -434,25 +434,25 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians //HAND HANDLING -/mob/living/simple_animal/hostile/guardian/equip_to_slot(obj/item/equipped_item, slot) +/mob/living/simple_animal/hostile/guardian/equip_to_slot(obj/item/equipping, slot, initial = FALSE, redraw_mob = FALSE, indirect_action = FALSE) if(!slot) return FALSE - if(!istype(equipped_item)) + if(!istype(equipping)) return FALSE . = TRUE - var/index = get_held_index_of_item(equipped_item) + var/index = get_held_index_of_item(equipping) if(index) held_items[index] = null update_held_items() - if(equipped_item.pulledby) - equipped_item.pulledby.stop_pulling() + if(equipping.pulledby) + equipping.pulledby.stop_pulling() - equipped_item.screen_loc = null // will get moved if inventory is visible - equipped_item.forceMove(src) - equipped_item.equipped(src, slot) - SET_PLANE_EXPLICIT(equipped_item, ABOVE_HUD_PLANE, src) + equipping.screen_loc = null // will get moved if inventory is visible + equipping.forceMove(src) + equipping.equipped(src, slot) + SET_PLANE_EXPLICIT(equipping, ABOVE_HUD_PLANE, src) /mob/living/simple_animal/hostile/guardian/proc/apply_overlay(cache_index) if((. = guardian_overlays[cache_index])) diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm index bdbc0e8f4d3..1a11d874ee8 100644 --- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm +++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm @@ -52,7 +52,7 @@ return TRUE return FALSE -/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/equipped_item, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE) +/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/equipped_item, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE, ignore_equipped = FALSE) switch(slot) if(ITEM_SLOT_DEX_STORAGE) if(internal_storage) @@ -70,13 +70,13 @@ return ITEM_SLOT_DEX_STORAGE return ..() -/mob/living/simple_animal/hostile/guardian/dextrous/equip_to_slot(obj/item/equipped_item, slot) +/mob/living/simple_animal/hostile/guardian/dextrous/equip_to_slot(obj/item/equipping, slot, initial = FALSE, redraw_mob = FALSE, indirect_action = FALSE) if(!..()) return switch(slot) if(ITEM_SLOT_DEX_STORAGE) - internal_storage = equipped_item + internal_storage = equipping update_inv_internal_storage() else to_chat(src, span_danger("You are trying to equip this item to an unsupported inventory slot. Report this to a coder!")) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 06c384aa211..09319223353 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -424,17 +424,19 @@ * unset redraw_mob to prevent the mob icons from being redrawn at the end. * * Initial is used to indicate whether or not this is the initial equipment (job datums etc) or just a player doing it + * + * set indirect_action to allow insertions into "soft" locked objects, things that are easily opened by the owning mob */ -/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, qdel_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, bypass_equip_delay_self = FALSE, initial = FALSE) +/mob/proc/equip_to_slot_if_possible(obj/item/W, slot, qdel_on_fail = FALSE, disable_warning = FALSE, redraw_mob = TRUE, bypass_equip_delay_self = FALSE, initial = FALSE, indirect_action = FALSE) if(!istype(W) || QDELETED(W)) //This qdeleted is to prevent stupid behavior with things that qdel during init, like say stacks return FALSE - if(!W.mob_can_equip(src, slot, disable_warning, bypass_equip_delay_self)) + if(!W.mob_can_equip(src, slot, disable_warning, bypass_equip_delay_self, indirect_action = indirect_action)) if(qdel_on_fail) qdel(W) else if(!disable_warning) to_chat(src, span_warning("You are unable to equip that!")) return FALSE - equip_to_slot(W, slot, initial, redraw_mob) //This proc should not ever fail. + equip_to_slot(W, slot, initial, redraw_mob, indirect_action = indirect_action) //This proc should not ever fail. return TRUE /** @@ -445,7 +447,7 @@ * *In most cases you will want to use equip_to_slot_if_possible() */ -/mob/proc/equip_to_slot(obj/item/W, slot) +/mob/proc/equip_to_slot(obj/item/equipping, slot, initial = FALSE, redraw_mob = FALSE, indirect_action = FALSE) return /** @@ -456,9 +458,10 @@ * * Also bypasses equip delay checks, since the mob isn't actually putting it on. * Initial is used to indicate whether or not this is the initial equipment (job datums etc) or just a player doing it + * set indirect_action to allow insertions into "soft" locked objects, things that are easily opened by the owning mob */ -/mob/proc/equip_to_slot_or_del(obj/item/W, slot, initial = FALSE) - return equip_to_slot_if_possible(W, slot, TRUE, TRUE, FALSE, TRUE, initial) +/mob/proc/equip_to_slot_or_del(obj/item/W, slot, initial = FALSE, indirect_action = FALSE) + return equip_to_slot_if_possible(W, slot, TRUE, TRUE, FALSE, TRUE, initial, indirect_action) /** * Auto equip the passed in item the appropriate slot based on equipment priority @@ -467,7 +470,7 @@ * * returns 0 if it cannot, 1 if successful */ -/mob/proc/equip_to_appropriate_slot(obj/item/W, qdel_on_fail = FALSE) +/mob/proc/equip_to_appropriate_slot(obj/item/W, qdel_on_fail = FALSE, indirect_action = FALSE) if(!istype(W)) return FALSE var/slot_priority = W.slot_equipment_priority @@ -485,7 +488,7 @@ ) for(var/slot in slot_priority) - if(equip_to_slot_if_possible(W, slot, FALSE, TRUE, TRUE, FALSE, FALSE)) //qdel_on_fail = FALSE; disable_warning = TRUE; redraw_mob = TRUE; + if(equip_to_slot_if_possible(W, slot, disable_warning = TRUE, redraw_mob = TRUE, indirect_action = indirect_action)) return TRUE if(qdel_on_fail) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index ab878f5e0eb..67763906e3f 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -19,17 +19,17 @@ . = ..() create_storage(max_specific_storage = max_w_class, max_total_storage = max_combined_w_class, max_slots = max_items) atom_storage.allow_big_nesting = TRUE - atom_storage.locked = TRUE + atom_storage.locked = STORAGE_FULLY_LOCKED /obj/item/mod/module/storage/on_install() var/datum/storage/modstorage = mod.create_storage(max_specific_storage = max_w_class, max_total_storage = max_combined_w_class, max_slots = max_items) modstorage.set_real_location(src) - atom_storage.locked = FALSE + atom_storage.locked = STORAGE_NOT_LOCKED 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 = TRUE + atom_storage.locked = STORAGE_FULLY_LOCKED qdel(modstorage) if(!deleting) atom_storage.remove_all(get_turf(src)) diff --git a/code/modules/research/xenobiology/crossbreeding/reproductive.dm b/code/modules/research/xenobiology/crossbreeding/reproductive.dm index 01868915dc2..88bfcb3379a 100644 --- a/code/modules/research/xenobiology/crossbreeding/reproductive.dm +++ b/code/modules/research/xenobiology/crossbreeding/reproductive.dm @@ -50,7 +50,7 @@ Reproductive extracts: return else if(istype(O, /obj/item/food/monkeycube)) - if(atom_storage?.attempt_insert(O, user, override = TRUE, force = TRUE)) + if(atom_storage?.attempt_insert(O, user, override = TRUE, force = STORAGE_FULLY_LOCKED)) to_chat(user, span_notice("You feed 1 Monkey Cube to [src], and it pulses gently.")) slime_storage?.processCubes(user) playsound(src, 'sound/items/eatfood.ogg', 20, TRUE) diff --git a/code/modules/unit_tests/outfit_sanity.dm b/code/modules/unit_tests/outfit_sanity.dm index 3e85464019a..683cba3b2fd 100644 --- a/code/modules/unit_tests/outfit_sanity.dm +++ b/code/modules/unit_tests/outfit_sanity.dm @@ -19,6 +19,26 @@ l_hand = /obj/item/stack/spacecash/c1000 r_hand = /obj/item/stack/spacecash/c1000 +/// outfit_sanity needs to cover insertions into duffelbags +/datum/outfit/duffel_user + name = "Mr. Runtime" + back = /obj/item/storage/backpack/duffelbag + backpack_contents = list(/obj/item/clothing/mask/cigarette/cigar/havana) + +/// Satchels too +/datum/outfit/stachel_user + name = "Mr. Runtime" + back = /obj/item/storage/backpack/satchel + backpack_contents = list(/obj/item/clothing/mask/cigarette/cigar/havana) + +/// And just in case we'll check backpacks +/datum/outfit/backpack_user + name = "Mr. Runtime" + back = /obj/item/storage/backpack + backpack_contents = list(/obj/item/clothing/mask/cigarette/cigar/havana) + + + /datum/unit_test/outfit_sanity/Run() var/datum/outfit/prototype_outfit = /datum/outfit var/prototype_name = initial(prototype_outfit.name) @@ -61,7 +81,7 @@ for (var/path in backpack_contents) var/number = backpack_contents[path] || 1 for (var/_ in 1 to number) - if (!H.equip_to_slot_or_del(new path(H), ITEM_SLOT_BACKPACK, TRUE)) + if (!H.equip_to_slot_or_del(new path(H), ITEM_SLOT_BACKPACK, TRUE, indirect_action = TRUE)) TEST_FAIL("[outfit.name]'s backpack_contents are invalid! Couldn't add [path] to backpack.") #undef CHECK_OUTFIT_SLOT