From 7dd932611f719b6e679f769d1e9e33f09b671c0f Mon Sep 17 00:00:00 2001 From: Kapu1178 <75460809+Kapu1178@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:04:48 -0400 Subject: [PATCH] Click-Drag can now be used to consistently manipulate inventories. (#505) * drag drop qol * swap held items * fixes a rare bug that hasnt even happened yet * fix bugs --- code/_onclick/drag_drop.dm | 2 +- code/_onclick/hud/screen_objects.dm | 79 +++++++++++++++++++++++++++++ code/datums/storage/storage.dm | 9 +--- code/game/objects/items.dm | 4 +- code/modules/mob/inventory.dm | 36 ++++++++++++- 5 files changed, 117 insertions(+), 13 deletions(-) diff --git a/code/_onclick/drag_drop.dm b/code/_onclick/drag_drop.dm index d0d280dc1940..c0c66ee216c6 100644 --- a/code/_onclick/drag_drop.dm +++ b/code/_onclick/drag_drop.dm @@ -12,7 +12,7 @@ return if(over == src) return usr.client.Click(src, src_location, src_control, params) - if(!Adjacent(usr) || !over.Adjacent(usr)) + if((!Adjacent(usr) || !over.Adjacent(usr)) && !istype(over, /atom/movable/screen)) return // should stop you from dragging through windows over.MouseDrop_T(src,usr, params) diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index 4cc785abf5df..4ce574355695 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -147,6 +147,23 @@ usr.update_held_items() return TRUE +/atom/movable/screen/inventory/MouseDrop_T(atom/dropped, mob/user, params) + if(user != hud?.mymob || !slot_id) + return TRUE + if(!isitem(dropped)) + return TRUE + if(world.time <= usr.next_move) + return TRUE + if(usr.incapacitated(IGNORE_STASIS)) + return TRUE + if(ismecha(usr.loc)) // stops inventory actions in a mech + return TRUE + if(!user.is_holding(dropped)) + return TRUE + + user.equip_to_slot_if_possible(dropped, slot_id, FALSE, FALSE, FALSE) + return TRUE + /atom/movable/screen/inventory/MouseEntered(location, control, params) . = ..() add_overlays() @@ -222,10 +239,13 @@ var/mob/user = hud?.mymob if(usr != user) return TRUE + if(world.time <= user.next_move) return TRUE + if(user.incapacitated()) return TRUE + if (ismecha(user.loc)) // stops inventory actions in a mech return TRUE @@ -237,6 +257,36 @@ user.swap_hand(held_index) return TRUE +/atom/movable/screen/inventory/hand/MouseDrop_T(atom/dropping, mob/user, params) + if(!isitem(dropping)) + return TRUE + + if(usr != hud?.mymob) + return TRUE + + if(world.time <= user.next_move) + return TRUE + + if(user.incapacitated()) + return TRUE + + if(ismecha(user.loc)) // stops inventory actions in a mech + return TRUE + + if(!user.CanReach(dropping)) + return TRUE + + var/obj/item/I = dropping + if(!(user.is_holding(I) || (I.item_flags & (IN_STORAGE|IN_INVENTORY)))) + return TRUE + + var/item_index = user.get_held_index_of_item(I) + if(item_index) + user.swapHeldIndexes(item_index, held_index) + else + user.putItemFromInventoryInHandIfPossible(dropping, held_index) + return TRUE + /atom/movable/screen/close name = "close" plane = ABOVE_HUD_PLANE @@ -409,6 +459,35 @@ return TRUE +/atom/movable/screen/storage/MouseDrop_T(atom/dropping, mob/user, params) + var/datum/storage/storage_master = master + + if(!istype(storage_master)) + return FALSE + + if(!isitem(dropping)) + return TRUE + + if(world.time <= user.next_move) + return TRUE + + if(user.incapacitated()) + return TRUE + + if(ismecha(user.loc)) // stops inventory actions in a mech + return TRUE + + if(!user.CanReach(dropping)) + return TRUE + + var/obj/item/I = dropping + if(!(user.is_holding(I) || (I.item_flags & IN_STORAGE))) + return TRUE + + storage_master.attempt_insert(dropping, usr) + + return TRUE + /atom/movable/screen/throw_catch name = "throw/catch" icon = 'icons/hud/screen_midnight.dmi' diff --git a/code/datums/storage/storage.dm b/code/datums/storage/storage.dm index 037ce6e875dc..3cf3fcba6be0 100644 --- a/code/datums/storage/storage.dm +++ b/code/datums/storage/storage.dm @@ -683,15 +683,8 @@ GLOBAL_LIST_EMPTY(cached_storage_typecaches) resolve_parent.add_fingerprint(user) - if(istype(over_object, /atom/movable/screen/inventory/hand)) - if(resolve_parent.loc != user) - return - - var/atom/movable/screen/inventory/hand/hand = over_object - user.putItemFromInventoryInHandIfPossible(resolve_parent, hand.held_index) - - else if(ismob(over_object)) + if(ismob(over_object)) if(over_object != user) return diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 3ba29ddbf8d2..7ff3d3de7923 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -509,7 +509,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons //If the item is in a storage item, take it out - loc.atom_storage?.attempt_remove(src, user.loc, silent = TRUE) + var/was_in_storage = loc.atom_storage?.attempt_remove(src, user.loc, silent = TRUE) if(QDELETED(src)) //moving it out of the storage to the floor destroyed it. return @@ -522,7 +522,7 @@ GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons . = FALSE pickup(user) add_fingerprint(user) - if(!user.put_in_active_hand(src, FALSE, FALSE)) + if(!user.put_in_active_hand(src, FALSE, was_in_storage)) user.dropItemToGround(src) return TRUE diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index c8ff336e9f52..0987fd3f546b 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -264,11 +264,41 @@ if(!temporarilyRemoveItemFromInventory(I, force_removal)) return FALSE I.remove_item_from_storage(src) - if(!put_in_hand(I, hand_index)) + if(!put_in_hand(I, hand_index, ignore_anim = TRUE)) qdel(I) CRASH("Assertion failure: putItemFromInventoryInHandIfPossible") //should never be possible return TRUE +/// Switches the items inside of two hand indexes. +/mob/proc/swapHeldIndexes(index_A, index_B) + if(index_A == index_B) + return + var/obj/item/item_A = get_item_for_held_index(index_A) + var/obj/item/item_B = get_item_for_held_index(index_B) + + var/failed_uh_oh_abort = FALSE + if(!(item_A || item_B)) + return + if(item_A && !temporarilyRemoveItemFromInventory(item_A)) + failed_uh_oh_abort = TRUE + if(item_B && !temporarilyRemoveItemFromInventory(item_B)) + failed_uh_oh_abort = TRUE + + if((item_A && !put_in_hand(item_A, index_B)) || (item_B && !put_in_hand(item_B, index_A))) + failed_uh_oh_abort = TRUE + + if(failed_uh_oh_abort) + if(item_A) + temporarilyRemoveItemFromInventory(item_A) + if(item_B) + temporarilyRemoveItemFromInventory(item_B) + if(item_A) + put_in_hand(item_A, index_A) + if(item_B) + put_in_hand(item_B, index_B) + return FALSE + return TRUE + //The following functions are the same save for one small difference /** @@ -347,8 +377,10 @@ * Argument(s): * * Optional - include_pockets (TRUE/FALSE), whether or not to include the pockets and suit storage in the returned list */ +/mob/proc/get_equipped_items(include_pockets = FALSE) + return -/mob/living/proc/get_equipped_items(include_pockets = FALSE) +/mob/living/get_equipped_items(include_pockets = FALSE) var/list/items = list() for(var/obj/item/item_contents in contents) if(item_contents.item_flags & IN_INVENTORY)