diff --git a/QuickStackToBag/Lua/Cyka/quickreload.lua b/QuickStackToBag/Lua/Cyka/quickreload.lua index 0b7fa4e..dbbdcd7 100644 --- a/QuickStackToBag/Lua/Cyka/quickreload.lua +++ b/QuickStackToBag/Lua/Cyka/quickreload.lua @@ -3,24 +3,77 @@ local cursormacroer = require("Cyka.cursormacroer") local utils = require("Cyka.utils") local dump = require("Cyka.dump") +-- Some items allow multiple items to be loaded +-- Such as welders and cutters +-- But we don't really want to disqualify those programmatically +-- Because it is not so obvious what item we REALLY want to load +-- So we will just hardcode tools and their whitelisted magazines +---@type table> +local LOAD_MAP = { +} + ---@param inventory Barotrauma.ItemInventory ----@param predicate fun(slot: InventorySlot): boolean ----@return InventorySlot[], string? -local function findSlotsThat(inventory, predicate) +---@return InventorySlot[] +local function getSlots(inventory) local slots = {} - for i, slot in ipairs(inventory.slots) do - local inventorySlot = { - slot = slot, + local inventorySlots = inventory.slots + for i, inventorySlot in ipairs(inventorySlots) do + slots[#slots + 1] = { inventory = inventory, - slotIndex = i - 1 + slotIndex = i - 1, + slot = inventorySlot } - if predicate(inventorySlot) then - slots[#slots + 1] = inventorySlot - end end return slots end +---@param from Barotrauma.ItemInventory +---@param slots InventorySlot[] +---@return table +local function getItemsPerSlot(from, slots) + -- How many items can we move to what slot + -- We don't yet know what can fit into what slot + ---@type table + local movableBySlot = {} + -- Get all the items and then we will sort them by condition and shit + utils.enqueueInventory(from, {}, function(ititem) + -- MyModGlobal.debugPrint("Checking item:") + -- dump(slots) + -- MyModGlobal.debugPrint(ititem.Prefab.Identifier.Value) + for _, inventorySlot in ipairs(slots) do + local canMove = inventorySlot.inventory.CanBePutInSlot(ititem, inventorySlot.slotIndex) + -- MyModGlobal.debugPrint(string.format("Can move to slot %d: %s", inventorySlot.slotIndex, tostring(canMove))) + if canMove then + movableBySlot[inventorySlot] = movableBySlot[inventorySlot] or {} + movableBySlot[inventorySlot][#movableBySlot[inventorySlot] + 1] = ititem + return true + end + end + return false + end) + return movableBySlot +end + +---@param movableBySlot table +---@return table> +local function getPermissibleItemsPerSlot(movableBySlot) + -- The point of this exercise is to eliminate slots that can have + -- Multiple items + -- What do we put into those? Any? All? + -- What if those slots belong to a container? + -- Are we reloading 30 slot containers? + ---@type table> + local permissibleItemsPerSlot = {} + for inventorySlot, items in pairs(movableBySlot) do + for _, ititem in ipairs(items) do + local thisone = tostring(ititem.Prefab.Identifier.Value) + permissibleItemsPerSlot[inventorySlot][thisone] = true + end + end + return permissibleItemsPerSlot +end + + ---@param slot InventorySlot ---@param preferMinCondition boolean local function tryReloadSlot(slot, preferMinCondition) @@ -36,17 +89,6 @@ local function tryReloadSlot(slot, preferMinCondition) return end - ---@type InventorySlot[] - local toLoad = {} - local inventorySlots = inventory.slots - for i, inventorySlot in ipairs(inventorySlots) do - toLoad[#toLoad + 1] = { - inventory = inventory, - slotIndex = i - 1, - slot = inventorySlot - } - end - local character = Character.Controlled if not character then MyModGlobal.debugPrint("No character") @@ -58,47 +100,24 @@ local function tryReloadSlot(slot, preferMinCondition) return end - -- How many items can we move to what slot - -- We don't yet know what can fit into what slot + ---@type InventorySlot[] + local slots = getSlots(inventory) + -- MyModGlobal.debugPrint("Slots:") + -- dump(slots) + ---@type table - local movableBySlot = {} - -- Get all the items and then we will sort them by condition and shit - utils.enqueueInventory(characterInventory, {}, function(ititem) - for _, inventorySlot in ipairs(toLoad) do - local canMove = inventorySlot.inventory.CanBePutInSlot(ititem, inventorySlot.slotIndex) - if canMove then - movableBySlot[inventorySlot] = movableBySlot[inventorySlot] or {} - movableBySlot[inventorySlot][#movableBySlot[inventorySlot] + 1] = ititem - return true - end - end - return false - end) - -- print("movableBySlot") + local movableBySlot = getItemsPerSlot(characterInventory, slots) + -- MyModGlobal.debugPrint("Movable by slot:") -- dump(movableBySlot) - -- The point of this exercise is to eliminate slots that can have - -- Multiple items - -- What do we put into those? Any? All? - -- What if those slots belong to a container? - -- Are we reloading 30 slot containers? - ---@type table - local permissibleItemsPerSlot = {} - for inventorySlot, items in pairs(movableBySlot) do - for _, ititem in ipairs(items) do - local existing = permissibleItemsPerSlot[inventorySlot] - local thisone = ititem.Prefab - if existing and not existing.Equals(thisone) then - print("Already have an item in this slot, can not have 2?") - movableBySlot[inventorySlot] = nil - end - permissibleItemsPerSlot[inventorySlot] = thisone - end + local permissibleItems = LOAD_MAP[tostring(item.Prefab.Identifier.Value)] + if not permissibleItems then + MyModGlobal.debugPrint("No permissible items for item") + local permissibleItemsPerSlot = getPermissibleItemsPerSlot(movableBySlot) + MyModGlobal.debugPrint("Can load per slot:") + dump(permissibleItemsPerSlot) + return end - -- print("permissibleItemsPerSlot") - -- dump(permissibleItemsPerSlot) - -- print("movableBySlot") - -- dump(movableBySlot) -- Sort items by condition (asc or desc) but also -- Make sure items with 0 condition are at the end @@ -116,7 +135,7 @@ local function tryReloadSlot(slot, preferMinCondition) end end) end - dump(movableBySlot) + -- dump(movableBySlot) for inventorySlot, items in pairs(movableBySlot) do for _, ititem in ipairs(items) do