Rework finding mouseover slots to not go over inventories that can not be open at this time
This commit is contained in:
@@ -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()
|
||||
|
@@ -338,5 +338,6 @@ return {
|
||||
sortItemTree = sortItemTree,
|
||||
tryMoveItem = tryMoveItem,
|
||||
tryMoveItems = tryMoveItems,
|
||||
quickStackItems = quickStackItems
|
||||
quickStackItems = quickStackItems,
|
||||
getOpenContainers = getOpenContainers
|
||||
}
|
||||
|
Reference in New Issue
Block a user