Completely and totally rework utils

This commit is contained in:
2025-04-01 18:49:22 +02:00
parent 07b42dfa05
commit 91b8576385

View File

@@ -1,15 +1,172 @@
-- luacheck: globals Character MyModGlobal -- luacheck: globals Character MyModGlobal Timer _
-- luacheck: max line length 420 -- luacheck: max line length 420
---@class ItemRefs ---@class Barotrauma.Inventory.ItemSlot
---@field item Barotrauma.Item ---@field items Barotrauma.Item[]
---@field inventory Barotrauma.ItemInventory
---@field slot Barotrauma.ItemInventory.Slot
-- local globalInventorySlotCache = {}
---@class InventorySlot ---@class InventorySlot
---@field slot Barotrauma.ItemSlot ---@field slot Barotrauma.Inventory.ItemSlot
---@field inventory Barotrauma.ItemInventory ---@field inventory Barotrauma.Inventory
---@field slotIndex number ---@field slotIndex1 number Lua based item slots
---@field slotIndex0 number Barotrauma API based item slots
---@field item Barotrauma.Item
---@field stackSize number
---@field maxStackSize number
-- ---@field lastUpdated number
MyModGlobal.InventorySlot = {
---@param inventory Barotrauma.Inventory
---@param slotIndex1 number
---@return InventorySlot
new = function(inventory, slotIndex1)
local self = setmetatable({}, {
__index = MyModGlobal.InventorySlot
})
self.inventory = inventory
self.slotIndex1 = slotIndex1
self.slotIndex0 = slotIndex1 - 1
-- self:update()
if inventory and inventory.slots and #inventory.slots > 0 then
self.slot = inventory.slots[slotIndex1]
end
if self.slot and self.slot.items and #self.slot.items > 0 then
self.item = self.slot.items[1]
self.stackSize = #self.slot.items
-- At this point inventory has to exist
-- If it didn't slot wouldn't either and then this wouldn't either
self.maxStackSize = self.item.Prefab.GetMaxStackSize(inventory)
end
return self
end,
update = function(self)
-- self.lastUpdated = Timer.GetTime()
if not self.inventory then
MyModGlobal.debugPrint("Error updating inventory slot, inventory not found")
return
end
if not self.inventory.slots then
MyModGlobal.debugPrint("Error updating inventory slot, inventory has no slots")
return
end
local slot = self.inventory.slots[self.slotIndex1]
if not slot then
MyModGlobal.debugPrint("Error updating inventory slot, slot not found")
return
end
self.slot = slot
if not slot.items or #slot.items == 0 then
-- MyModGlobal.debugPrint("Error updating inventory slot, slot is empty")
return
end
self.item = slot.items[1]
self.stackSize = #slot.items
self.maxStackSize = self.item.Prefab.GetMaxStackSize(self.inventory)
end,
__tostring = function(self)
return string.format(
"InventorySlot(inventory=%s, slotIndex1=%d, slotIndex0=%d, item=%s, stackSize=%d, maxStackSize=%d)",
tostring(self.inventory), self.slotIndex1, self.slotIndex0, tostring(self.item), self.stackSize,
self.maxStackSize)
end,
---@param predicate? fun(slot: InventorySlot): boolean
getNearbySlots = function(self, predicate)
predicate = predicate or function() return true end
local slotsPerRow = 900
local ok, err = pcall(function()
slotsPerRow = self.inventory.slotsPerRow
end)
if not ok then
MyModGlobal.debugPrint(string.format("Error getting slots per row: %s", err))
end
local getGridPos = function(slotIndex)
local x = slotIndex % slotsPerRow
local y = math.floor(slotIndex / slotsPerRow)
return x, y
end
local slots = {}
for slotIndex, _ in ipairs(self.inventory.slots) do
local inventorySlot = MyModGlobal.InventorySlot.new(self.inventory, slotIndex)
if predicate(inventorySlot) then
slots[#slots + 1] = inventorySlot
end
end
local slotx, sloty = getGridPos(self.slotIndex0)
table.sort(slots, function(a, b)
local ax, ay = getGridPos(a.slotIndex0)
local bx, by = getGridPos(b.slotIndex0)
-- Chebyshev distance
local distA = math.max(math.abs(ax - slotx), math.abs(ay - sloty))
local distB = math.max(math.abs(bx - slotx), math.abs(by - sloty))
if distA == distB then
return a.slotIndex0 < b.slotIndex0
end
return distA < distB
end)
return slots
end,
-- hash = function(self)
-- return string.format("%s:%d:%d", tostring(self.inventory), self.slotIndex1, self.slotIndex0)
-- end
}
---@class ItemMoveRequest
---@field A InventorySlot
---@field B InventorySlot
---@field allowSwap boolean
---@field allowCombine boolean
local enqueueMove
do
-- A bit of cheeky scoping
local enabled = true
---@type ItemMoveRequest[]
local itemMoveQueue = {}
local rate = 10
local function processQueue()
MyModGlobal.debugPrint("Processing queue")
Timer.Wait(processQueue, rate)
if not enabled then return end
if #itemMoveQueue == 0 then return end
---@type ItemMoveRequest
local moveRequest = table.remove(itemMoveQueue, 1)
-- TODO: Maybe try and figure out if we CAN put A into B
moveRequest.allowCombine = moveRequest.allowCombine or false
moveRequest.allowSwap = moveRequest.allowSwap or false
local success = moveRequest.B.inventory.TryPutItem(moveRequest.A.item, moveRequest.B.slotIndex0,
moveRequest.allowSwap, moveRequest.allowCombine, Character.Controlled, true)
if not success then
MyModGlobal.debugPrint(string.format("Failed moving item from %s to %s", tostring(moveRequest.A),
tostring(moveRequest.B)))
end
end
processQueue()
---@param A InventorySlot
---@param B InventorySlot
---@param allowSwap boolean
---@param allowCombine boolean
enqueueMove = function(A, B, allowSwap, allowCombine)
MyModGlobal.debugPrint(string.format("Enqueuing move from %s to %s", tostring(A), tostring(B)))
table.insert(itemMoveQueue, {
A = A,
B = B,
allowSwap = allowSwap,
allowCombine = allowCombine,
})
end
end
---@return Barotrauma.Item[], string? ---@return Barotrauma.Item[], string?
local function getOpenContainers() local function getOpenContainers()
@@ -23,7 +180,9 @@ end
---@return Barotrauma.Item, string? ---@return Barotrauma.Item, string?
local function getFirstOpenContainer() local function getFirstOpenContainer()
local containers, err = getOpenContainers() local containers, err = getOpenContainers()
---@diagnostic disable-next-line: return-type-mismatch
if err then return nil, err end if err then return nil, err end
---@diagnostic disable-next-line: return-type-mismatch
if #containers == 0 then return nil, "No open containers" end if #containers == 0 then return nil, "No open containers" end
return containers[1], nil return containers[1], nil
end end
@@ -32,194 +191,230 @@ end
-- And enqueueItem calls enqueueInventory -- And enqueueItem calls enqueueInventory
-- So unless we define them both before using them -- So unless we define them both before using them
-- We will get an error saying either is undefined -- We will get an error saying either is undefined
-- TODO: Rework these enqueue functions to accept a params object
-- That will house all optional parameters
-- And in that include recurse boolean
---@class ItemRefs
---@field item Barotrauma.Item
---@field inventory Barotrauma.Inventory
---@field slot Barotrauma.Inventory.ItemSlot
---@field slotIndex1 number
---@class EnqueueOptions
---@field itemQueue Barotrauma.Item[]
---@field slotQueue Barotrauma.Inventory.ItemSlot[]
---@field inventoryQueue Barotrauma.Inventory[]
---@field itemPredicate fun(item: Barotrauma.Item, itemRef: ItemRefs): boolean
---@field slotPredicate fun(slot: Barotrauma.Inventory.ItemSlot, itemRef: ItemRefs): boolean
---@field inventoryPredicate fun(inventory: Barotrauma.Inventory, itemRef: ItemRefs): boolean
---@field loadRefs boolean
---@field itemRef ItemRefs
---@field recurse boolean
---@param options EnqueueOptions
---@return EnqueueOptions
local function ensureOptionsDefaults(options)
options = options or {}
options.itemQueue = options.itemQueue or {}
options.slotQueue = options.slotQueue or {}
options.inventoryQueue = options.inventoryQueue or {}
options.itemPredicate = options.itemPredicate or function() return true end
options.slotPredicate = options.slotPredicate or function() return true end
options.inventoryPredicate = options.inventoryPredicate or function() return true end
options.loadRefs = options.loadRefs or false
options.itemRef = options.itemRef or nil
options.recurse = options.recurse or true
return options
end
local enqueueItem local enqueueItem
local enqueueSlot local enqueueSlot
local enqueueInventory local enqueueInventory
local enqueuePlayerItems
local enqueueOpenContainers local enqueueOpenContainers
local allPlayerItems local enqueueSubmarineItems
local allSubmarineItems local enqueueAllOwnedItems
local allOwnedItems
local _
---@alias FilterPredicate fun(item: Barotrauma.Item, inventoryRef?: Barotrauma.ItemInventory, slotRef: Barotrauma.ItemInventory.Slot): boolean do
---@param item Barotrauma.Item
---@param options EnqueueOptions
---@return EnqueueOptions, string?
enqueueItem = function(item, options)
options = ensureOptionsDefaults(options)
if not item then return options.itemQueue, "No item" end
-- Loading refs is optional because it MAY have a performance impact local ok, stop = options.itemPredicate(item, options.itemRef)
---@param item Barotrauma.Item
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@param loadRefs? boolean
---@param itemRef? ItemRefs
---@return Barotrauma.Item[], string?
enqueueItem = function(item, queue, predicate, loadRefs, itemRef)
queue = queue or {}
predicate = predicate or function() return true end
itemRef = itemRef or {}
-- debugPrint(string.format("Enqueuing item: %s", item.Prefab.Identifier.Value))
-- local err
-- This should make it breadth first, right...?
-- No, not yet...
if not item then return queue, "No item" end
local ok, stop = predicate(item, itemRef)
if ok then if ok then
queue[#queue + 1] = item options.itemQueue[#options.itemQueue + 1] = item
end end
if stop then return queue, "Stop" end if stop then return options.itemQueue, "Stop" end
local err
if item.OwnInventory then if item.OwnInventory then
-- As far as I know every item has only one inventory -- As far as I know every item has only one inventory
-- Only machines have multiple -- Only machines have multiple
-- So inventrorY should be fine here -- So inventrorY should be fine here
-- debugPrint("Item has its own inventory, enqueuing inventory...") if options.recurse then
if loadRefs then if options.loadRefs then
itemRef.item = item options.itemRef.item = item
queue, _ = enqueueInventory(item.OwnInventory, queue, predicate, loadRefs, itemRef) options.inventoryQueue, err = enqueueInventory(item.OwnInventory, options)
else else
queue, _ = enqueueInventory(item.OwnInventory, queue, predicate, itemRef) options.inventoryQueue, err = enqueueInventory(item.OwnInventory, options)
end end
-- if err then
-- debugPrint(string.format("Error enqueuing inventory: %s", err))
-- end
end end
-- debugPrint(string.format("Item enqueued. Current queue size: %d", #queue)) end
return queue, nil return options, err
end end
---@param slot Barotrauma.ItemInventory.Slot ---@param slot Barotrauma.Inventory.ItemSlot
---@param queue Barotrauma.Item[] ---@param options EnqueueOptions
---@param predicate? FilterPredicate ---@return EnqueueOptions, string?
---@param loadRefs? boolean enqueueSlot = function(slot, options)
---@param itemRef? ItemRefs options = ensureOptionsDefaults(options)
---@return Barotrauma.Item[], string? if not slot then return options, "No slot" end
enqueueSlot = function(slot, queue, predicate, loadRefs, itemRef) if not slot.items then return options, "No items" end
queue = queue or {}
predicate = predicate or function() return true end local ok, stop = options.slotPredicate(slot, options.itemRef)
itemRef = itemRef or {} if ok then
-- debugPrint(string.format("Enqueuing slot with %d items.", #slot.items)) options.slotQueue[#options.slotQueue + 1] = slot
-- We don't want to shadow queue end
local err if stop then return options, "Stop" end
-- If the slot is empty there's nothing to iterate
-- And we will naturally return queue as is
if not slot then return queue, "No slot" end
if not slot.items then return queue, "No items" end
for _, item in ipairs(slot.items) do for _, item in ipairs(slot.items) do
-- Only the final leaf nodes decide upon the predicate -- We redeclare err every iteration so it doesn't spill over
if loadRefs then
itemRef.slot = slot
queue, err = enqueueItem(item, queue, predicate, loadRefs, itemRef)
else
queue, err = enqueueItem(item, queue, predicate)
end
if err then
return queue, err
end
end
-- debugPrint(string.format("Finished enqueuing slot. Current queue size: %d", #queue))
return queue
end
---@param inventory Barotrauma.ItemInventory
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@param loadRefs? boolean
---@param itemRef? ItemRefs
---@return Barotrauma.Item[], string?
enqueueInventory = function(inventory, queue, predicate, loadRefs, itemRef)
queue = queue or {}
predicate = predicate or function() return true end
itemRef = itemRef or {}
-- debugPrint(string.format("Enqueuing inventory with %d slots.", #inventory.slots))
local err local err
if not inventory then return queue, "No inventory" end if options.loadRefs then
if not inventory.slots then return queue, "No slots" end options.itemRef.slot = slot
options, err = enqueueItem(item, options)
for _, slot in ipairs(inventory.slots) do
-- Only the final leaf nodes decide upon the predicate
if loadRefs then
itemRef.inventory = inventory
queue, err = enqueueSlot(slot, queue, predicate, loadRefs, itemRef)
else else
queue, err = enqueueSlot(slot, queue, predicate) options, err = enqueueItem(item, options)
end end
if err then if err then
return queue, err return options, err
end end
end end
-- debugPrint(string.format("Finished enqueuing inventory. Current queue size: %d", #queue)) return options
return queue end
end
local relevantPlayerInventorySlots = { 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, MyModGlobal.BAG_SLOT } ---@param inventory Barotrauma.Inventory
---@param queue Barotrauma.Item[] ---@param options EnqueueOptions
---@param predicate? FilterPredicate ---@return EnqueueOptions, string?
---@param loadRefs? boolean enqueueInventory = function(inventory, options)
---@return Barotrauma.Item[], string? options = ensureOptionsDefaults(options)
allPlayerItems = function(queue, predicate, loadRefs) if not inventory then return options, "No inventory" end
queue = queue or {} if not inventory.slots then return options, "No slots" end
predicate = predicate or function() return true end
local ok, stop = options.inventoryPredicate(inventory, options.itemRef)
if ok then
options.inventoryQueue[#options.inventoryQueue + 1] = inventory
end
if stop then return options, "Stop" end
for i, slot in ipairs(inventory.slots) do
local err
if options.loadRefs then
options.itemRef.inventory = inventory
options.itemRef.slot = slot
options.itemRef.slotIndex1 = i
options, err = enqueueSlot(slot, options)
else
options, err = enqueueSlot(slot, options)
end
if err then
return options, err
end
end
return options
end
local relevantPlayerInventorySlots = {
false,
false,
false,
false,
false,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
true,
}
---@param options EnqueueOptions
---@return EnqueueOptions, string?
enqueuePlayerItems = function(options)
options = ensureOptionsDefaults(options)
local character = Character.Controlled local character = Character.Controlled
if not character then return queue, "No character" end if not character then return options, "No character" end
local inventory = character.Inventory local inventory = character.Inventory
if not inventory then return queue, "No inventory" end if not inventory then return options, "No inventory" end
for _, slotid in ipairs(relevantPlayerInventorySlots) do options.loadRefs = true
local slot = inventory.slots[slotid] options.itemPredicate = function(item)
local err if not item then return false end
local parentInventory = item.ParentInventory
if not slot then goto continue end if not parentInventory then return false end
if #slot.items == 0 then goto continue end if not parentInventory.Equals(inventory) then return false end
return true
queue, err = enqueueSlot(slot, queue, predicate, loadRefs) end
if err then return queue, err end options.slotPredicate = function(slot, itemRef)
if not slot then return false end
::continue:: if itemRef.slotIndex1 and relevantPlayerInventorySlots[itemRef.slotIndex1] then
return true
end
return false
end end
return queue local err
end options, err = enqueueInventory(inventory, options)
if err then return options, err end
---@param queue Barotrauma.Item[] return options
---@param predicate? FilterPredicate end
---@param loadRefs? boolean
---@return Barotrauma.Item[], string? ---@param options EnqueueOptions
enqueueOpenContainers = function(queue, predicate, loadRefs) ---@return EnqueueOptions, string?
queue = queue or {} enqueueOpenContainers = function(options)
predicate = predicate or function() return true end options = ensureOptionsDefaults(options)
local containers, err = getOpenContainers() local containers, err = getOpenContainers()
if err then return queue, err end if err then return options, err end
for _, container in ipairs(containers) do for _, container in ipairs(containers) do
local inventories = container.OwnInventories local inventories = container.OwnInventories
if not inventories then goto continue end if not inventories then goto continue end
for containerInventory in inventories do for containerInventory in inventories do
queue, err = enqueueInventory(containerInventory, queue, predicate, loadRefs) options, err = enqueueInventory(containerInventory, options)
if err then return queue, err end if err then return options, err end
end end
::continue:: ::continue::
end end
return queue return options
end end
---@param options EnqueueOptions
---@return EnqueueOptions, string?
enqueueSubmarineItems = function(options)
options = ensureOptionsDefaults(options)
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@return Barotrauma.Item[], string?
allSubmarineItems = function(queue, predicate)
queue = queue or {}
predicate = predicate or function() return true end
-- This only exists so predicate does not explode -- This only exists so predicate does not explode
-- Even if its empty -- Even if its empty
local itemRef = {} local itemRef = {}
local character = Character.Controlled local character = Character.Controlled
if not character then return queue, "No character" end if not character then return options, "No character" end
local submarine = character.Submarine local submarine = character.Submarine
if not submarine then return queue, "No submarine" end if not submarine then return options, "No submarine" end
for item in submarine.GetItems(false) do for item in submarine.GetItems(false) do
-- We do NOT want to call enqueueItem here because enqueueItem -- We do NOT want to call enqueueItem here because enqueueItem
@@ -227,32 +422,30 @@ allSubmarineItems = function(queue, predicate)
-- And this call (GetItems) already gets all items -- And this call (GetItems) already gets all items
-- So we would be doing double the work (at best case) -- So we would be doing double the work (at best case)
-- It also means we won't have refs here which sucks -- It also means we won't have refs here which sucks
local ok, stop = predicate(item, itemRef) local ok, stop = options.itemPredicate(item, itemRef)
if ok then if ok then
queue[#queue + 1] = item options.itemQueue[#options.itemQueue + 1] = item
end end
if stop then return queue, "Stop" end if stop then return options, "Stop" end
end end
return queue return options
end end
---@param queue Barotrauma.Item[] ---@param options EnqueueOptions
---@param predicate? FilterPredicate ---@return EnqueueOptions, string?
---@param loadRefs? boolean enqueueAllOwnedItems = function(options)
---@return Barotrauma.Item[], string? options = ensureOptionsDefaults(options)
allOwnedItems = function(queue, predicate, loadRefs)
queue = queue or {}
predicate = predicate or function() return true end
local err local err
queue, err = allPlayerItems(queue, predicate, loadRefs) options, err = enqueuePlayerItems(options)
if err then return queue, err end if err then return options, err end
queue, err = allSubmarineItems(queue, predicate) options, err = enqueueSubmarineItems(options)
if err then return queue, err end if err then return options, err end
return queue return options
end
end end
-- There is actually no need to recurse deep -- There is actually no need to recurse deep
@@ -260,8 +453,8 @@ end
-- And not an item in an item in the inventory -- And not an item in an item in the inventory
-- So in theory we only need to recurse 1 deep -- So in theory we only need to recurse 1 deep
---@param inventory Barotrauma.Inventory ---@param inventory Barotrauma.Inventory
---@param slots InventorySlot[] ---@param slots? InventorySlot[]
---@param depth number ---@param depth? number
---@return InventorySlot[], string? ---@return InventorySlot[], string?
local function getMouseoverSlots(inventory, slots, depth) local function getMouseoverSlots(inventory, slots, depth)
slots = slots or {} slots = slots or {}
@@ -269,7 +462,7 @@ local function getMouseoverSlots(inventory, slots, depth)
if depth > 1 then return slots, nil end if depth > 1 then return slots, nil end
local visualSlots = inventory.visualSlots local visualSlots = inventory.visualSlots
if not visualSlots then return nil, "Inventory has no visual slots" end if not visualSlots then return slots, "Inventory has no visual slots" end
for i, visualSlot in ipairs(visualSlots) do for i, visualSlot in ipairs(visualSlots) do
local item local item
@@ -305,11 +498,8 @@ local function getMouseoverSlots(inventory, slots, depth)
::mouseover:: ::mouseover::
if visualSlot:MouseOn() then if visualSlot:MouseOn() then
slots[#slots + 1] = { local inventorySlot = MyModGlobal.InventorySlot.new(inventory, i)
inventory = inventory, slots[#slots + 1] = inventorySlot
slotIndex = i,
slot = slot
}
end end
::continue:: ::continue::
@@ -320,15 +510,17 @@ end
---@return InventorySlot[], string? ---@return InventorySlot[], string?
local function getSlotsUnderCursor() local function getSlotsUnderCursor()
local slots = {}
-- Make sure we have a controlled character -- Make sure we have a controlled character
local controlledCharacter = Character.Controlled local controlledCharacter = Character.Controlled
if not controlledCharacter then return nil, "No controlled character" end if not controlledCharacter then return slots, "No controlled character" end
local inventory = controlledCharacter.Inventory local inventory = controlledCharacter.Inventory
if not inventory then return nil, "No inventory" end if not inventory then return slots, "No inventory" end
local mouseoverSlots, err = getMouseoverSlots(inventory) local err
if err then return mouseoverSlots, err end slots, err = getMouseoverSlots(inventory, slots)
if err then return slots, err end
-- Even if we don't get them we're still fine -- Even if we don't get them we're still fine
local openContainers, _ = getOpenContainers() local openContainers, _ = getOpenContainers()
@@ -337,33 +529,28 @@ local function getSlotsUnderCursor()
for _, container in ipairs(openContainers) do for _, container in ipairs(openContainers) do
local containerInventories = container.OwnInventories local containerInventories = container.OwnInventories
for containerInventory in containerInventories do for containerInventory in containerInventories do
local slot
if not containerInventory or not containerInventory.visualSlots then if not containerInventory or not containerInventory.visualSlots then
MyModGlobal.debugPrint("Container inventory has no visual slots") MyModGlobal.debugPrint("Container inventory has no visual slots")
goto continue goto continue
end end
for i, visualSlot in ipairs(containerInventory.visualSlots) do for i, visualSlot in ipairs(containerInventory.visualSlots) do
if visualSlot:MouseOn() then if visualSlot:MouseOn() then
slot = containerInventory.slots[i] local inventorySlot = MyModGlobal.InventorySlot.new(containerInventory, i)
mouseoverSlots[#mouseoverSlots + 1] = { slots[#slots + 1] = inventorySlot
inventory = containerInventory,
slotIndex = i,
slot = slot
}
end end
end end
::continue:: ::continue::
end end
end end
return mouseoverSlots, nil return slots, nil
end end
---@return InventorySlot, string? ---@return InventorySlot, string?
local function getFirstSlotUnderCursor() local function getFirstSlotUnderCursor()
local slots, err = getSlotsUnderCursor() local slots, err = getSlotsUnderCursor()
if err then return nil, err end if err then return slots, err end
if #slots == 0 then return nil, "No slots found under cursor" end if #slots == 0 then return slots, "No slots found under cursor" end
for _, slot in ipairs(slots) do for _, slot in ipairs(slots) do
if slot.slot.items and #slot.slot.items > 0 then if slot.slot.items and #slot.slot.items > 0 then
return slot return slot
@@ -376,12 +563,13 @@ return {
enqueueItem = enqueueItem, enqueueItem = enqueueItem,
enqueueSlot = enqueueSlot, enqueueSlot = enqueueSlot,
enqueueInventory = enqueueInventory, enqueueInventory = enqueueInventory,
enqueueAllPlayerItems = allPlayerItems, enqueuePlayerItems = enqueuePlayerItems,
enqueueAllSubmarineItems = allSubmarineItems, enqueueSubmarineItems = enqueueSubmarineItems,
enqueueAllOwnedItems = allOwnedItems, enqueueAllOwnedItems = enqueueAllOwnedItems,
enqueueOpenContainers = enqueueOpenContainers, enqueueOpenContainers = enqueueOpenContainers,
getOpenContainers = getOpenContainers, getOpenContainers = getOpenContainers,
getFirstOpenContainer = getFirstOpenContainer, getFirstOpenContainer = getFirstOpenContainer,
getSlotsUnderCursor = getSlotsUnderCursor, getSlotsUnderCursor = getSlotsUnderCursor,
getFirstSlotUnderCursor = getFirstSlotUnderCursor, getFirstSlotUnderCursor = getFirstSlotUnderCursor,
enqueueMove = enqueueMove,
} }