From e463b84bf6d4651bb4330c33b0dc280d170404ab Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Sun, 30 Mar 2025 18:22:17 +0200 Subject: [PATCH] Rework finding mouseover slots to not go over inventories that can not be open at this time --- QuickStackToBag/Lua/Cyka/cursormacroer.lua | 153 +++++++++++++-------- QuickStackToBag/Lua/Cyka/quickstack.lua | 3 +- 2 files changed, 99 insertions(+), 57 deletions(-) diff --git a/QuickStackToBag/Lua/Cyka/cursormacroer.lua b/QuickStackToBag/Lua/Cyka/cursormacroer.lua index a045553..1635ad9 100644 --- a/QuickStackToBag/Lua/Cyka/cursormacroer.lua +++ b/QuickStackToBag/Lua/Cyka/cursormacroer.lua @@ -1,121 +1,162 @@ local quickstack = require("Cyka.quickstack") local utils = require("Cyka.utils") ----@return Barotrauma.VisualSlot|nil, Barotrauma.Inventory|nil, Barotrauma.Inventory.ItemSlot|nil +-- There is actually no need to recurse deep +-- Because we can only have an item in the inventory open +-- And not an item in an item in the inventory +-- So in theory we only need to recurse 1 deep +---@param inventory Barotrauma.Inventory +---@param slots Barotrauma.Inventory.SlotReference[] +---@return Barotrauma.Inventory.SlotReference[], string? +local function getMouseoverSlots(inventory, slots, depth) + slots = slots or {} + depth = depth or 0 + if depth > 1 then return slots, nil end + + local visualSlots = inventory.visualSlots + if not visualSlots then return nil, "Inventory has no visual slots" end + + for i, visualSlot in ipairs(visualSlots) do + local item + local itemInventory + -- local err + + local slot = inventory.slots[i] + if not slot then + -- MyModGlobal.debugPrint("Slot is not a valid slot") + goto continue + end + + if #slot.items == 0 then + goto mouseover + end + + item = slot.items[1] + if not item then + goto mouseover + end + + itemInventory = item.OwnInventory + if not itemInventory then + goto mouseover + end + + -- print("Before: " .. #slots)-- + getMouseoverSlots(itemInventory, slots, depth + 1) + -- if err then + -- MyModGlobal.debugPrint(string.format("Error getting mouseover slots: %s", err)) + -- end + -- print("After: " .. #slots) + + ::mouseover:: + if visualSlot:MouseOn() then + slots[#slots + 1] = slot + end + + ::continue:: + end + + return slots, nil +end + +---@return Barotrauma.Inventory.ItemSlot[]?, string? local function getInventorySlotUnderCursor() -- Make sure we have a controlled character local controlledCharacter = Character.Controlled - if not controlledCharacter then return nil, nil, nil end + if not controlledCharacter then return nil, "No controlled character" end - -- Check player inventory first - local charInventory = controlledCharacter.Inventory - if charInventory and charInventory.visualSlots then - for i, visualSlot in ipairs(charInventory.visualSlots) do - -- Check if mouse is over this slot - if visualSlot:MouseOn() then - local slot = charInventory.slots[i] - return visualSlot, charInventory, slot - end - end - end + local inventory = controlledCharacter.Inventory + if not inventory then return nil, "No inventory" end - -- Check if selected item has inventory (containers, etc.) - local selectedItem = controlledCharacter.SelectedItem - if selectedItem and selectedItem.OwnInventory and selectedItem.OwnInventory.visualSlots then - local itemInv = selectedItem.OwnInventory - for i, visualSlot in ipairs(itemInv.visualSlots) do - if visualSlot:MouseOn() then - local slot = itemInv.slots[i] - return visualSlot, itemInv, slot - end - end - end + local mouseoverSlots, err = getMouseoverSlots(inventory) + if err then return mouseoverSlots, err end - -- Check open containers or other items with visible inventories - for item in Item.ItemList do - if item and item.OwnInventory and item.OwnInventory.visualSlots then - local itemInv = item.OwnInventory - for i, visualSlot in ipairs(itemInv.visualSlots) do + local openContainers = quickstack.getOpenContainers() + for _, container in ipairs(openContainers) do + local containerInventories = container.OwnInventories + for containerInventory in containerInventories do + for i, visualSlot in ipairs(containerInventory.visualSlots) do if visualSlot:MouseOn() then - local slot = itemInv.slots[i] - return visualSlot, itemInv, slot + local slot = containerInventory.slots[i] + mouseoverSlots[#mouseoverSlots + 1] = slot end end end end - return nil, nil, nil + return mouseoverSlots, nil end local targetInventory = nil local function tryStackCursorItem() - local visualSlot, itemInv, slot = getInventorySlotUnderCursor() - if not visualSlot or not itemInv or not slot then - MyModGlobal.debugPrint(string.format("No inventory slot or item found")) + local slots, err = getInventorySlotUnderCursor() + if err then + -- MyModGlobal.debugPrint(string.format("Error getting inventory slot: %s", err)) return end - -- MyModGlobal.debugPrint(string.format("Visual slot: %s", tostring(visualSlot))) - -- MyModGlobal.debugPrint(string.format("Item inventory: %s", tostring(itemInv))) - -- MyModGlobal.debugPrint(string.format("Inventory slot: %s", tostring(slot))) - if not slot or not slot.items or not slot.items[1] then - MyModGlobal.debugPrint("No items in slot") + if not slots or #slots == 0 then + -- MyModGlobal.debugPrint("No items in slot") return end local inventory = targetInventory - MyModGlobal.debugPrint(string.format("Target inventory: %s", tostring(inventory))) + -- MyModGlobal.debugPrint(string.format("Target inventory: %s", tostring(inventory))) if not inventory then local controlledCharacter = Character.Controlled if not controlledCharacter then - MyModGlobal.debugPrint("No controlled character found") + -- MyModGlobal.debugPrint("No controlled character found") return end local cinventory = controlledCharacter.Inventory if not cinventory or not cinventory.slots then - MyModGlobal.debugPrint("No inventory found") + -- MyModGlobal.debugPrint("No inventory found") return end local bagSlot = cinventory.slots[MyModGlobal.BAG_SLOT] if not bagSlot or not bagSlot.items or not bagSlot.items[1] then - MyModGlobal.debugPrint("No bag slot found") + -- MyModGlobal.debugPrint("No bag slot found") return end local bagItem = bagSlot.items[1] if not bagItem or not bagItem.OwnInventory then - MyModGlobal.debugPrint("Bag item has no own inventory") + -- MyModGlobal.debugPrint("Bag item has no own inventory") return end local bagInventory = bagItem.OwnInventory if not bagInventory or not bagInventory.slots then - MyModGlobal.debugPrint("Bag inventory has no slots") + -- MyModGlobal.debugPrint("Bag inventory has no slots") return end inventory = bagInventory end if not inventory then - MyModGlobal.debugPrint("No inventory found") + -- MyModGlobal.debugPrint("No inventory found") return end - local itemTree, err = quickstack.buildItemTree(inventory) + local itemTree + itemTree, err = quickstack.buildItemTree(inventory) if err then - MyModGlobal.debugPrint(string.format("Error building item tree: %s", err)) + -- MyModGlobal.debugPrint(string.format("Error building item tree: %s", err)) return end itemTree = quickstack.sortItemTree(itemTree) - local itemsToMove = utils.enqueueSlot(slot) - for _, item in ipairs(itemsToMove) do - MyModGlobal.debugPrint(string.format("Enqueued item: %s", tostring(item))) + local itemsToMove = {} + for _, slot in ipairs(slots) do + utils.enqueueSlot(slot, itemsToMove) end - -- MyModGlobal.debugPrint(string.format("Enqueued %d items from the inventory slot", #itemsToMove)) + -- for _, item in ipairs(itemsToMove) do + -- MyModGlobal.debugPrint(string.format("Enqueued item: %s", tostring(item))) + -- end + -- -- MyModGlobal.debugPrint(string.format("Enqueued %d items from the inventory slot", #itemsToMove)) -- MyModGlobal.DumpTable(itemTree) local errors = quickstack.tryMoveItems(itemsToMove, itemTree, true) - for _, error in ipairs(errors) do - MyModGlobal.debugPrint(string.format("Error moving item: %s", error)) - end + -- for _, error in ipairs(errors) do + -- MyModGlobal.debugPrint(string.format("Error moving item: %s", error)) + -- end end local function setTargetInventory() diff --git a/QuickStackToBag/Lua/Cyka/quickstack.lua b/QuickStackToBag/Lua/Cyka/quickstack.lua index 020d986..a34a2b2 100644 --- a/QuickStackToBag/Lua/Cyka/quickstack.lua +++ b/QuickStackToBag/Lua/Cyka/quickstack.lua @@ -338,5 +338,6 @@ return { sortItemTree = sortItemTree, tryMoveItem = tryMoveItem, tryMoveItems = tryMoveItems, - quickStackItems = quickStackItems + quickStackItems = quickStackItems, + getOpenContainers = getOpenContainers }