diff --git a/CykaQuick/Lua/Cyka/quickreload.lua b/CykaQuick/Lua/Cyka/quickreload.lua index f6b5220..246947c 100644 --- a/CykaQuick/Lua/Cyka/quickreload.lua +++ b/CykaQuick/Lua/Cyka/quickreload.lua @@ -16,14 +16,13 @@ local LOAD_MAP = require("Cyka.quickreload_loadmap") ---@param inventory Barotrauma.ItemInventory ---@return InventorySlot[] local function getSlots(inventory) + ---@type InventorySlot[] local slots = {} + ---@type Barotrauma.Inventory.ItemSlot[] local inventorySlots = inventory.slots - for i, inventorySlot in ipairs(inventorySlots) do - slots[#slots + 1] = { - inventory = inventory, - slotIndex = i - 1, - slot = inventorySlot - } + for i, _ in ipairs(inventorySlots) do + local invSlot = MyModGlobal.InventorySlot.new(inventory, i) + slots[#slots + 1] = invSlot end return slots end @@ -36,28 +35,33 @@ local function getItemsPerSlot(slots) ---@type table local movableBySlot = {} -- Get all the items and then we will sort them by condition and shit - utils.enqueueAllPlayerItems({}, function(ititem, itemRef) - -- We don't want to take oxygen out of our diving suit to load our plasma cutter - -- Most loadable items have 1 capacity - -- But some have 2 or 3 (coil speargun) - if itemRef and itemRef.inventory and itemRef.inventory.Capacity < 4 then - -- MyModGlobal.debugPrint(string.format("Skipping small inventory %s", tostring(itemRef.inventory))) + utils.enqueuePlayerItems({ + recurse = true, + loadRefs = true, + itemPredicate = function(ititem, itemRef) + MyModGlobal.debugPrint(string.format("Checking item: %s", tostring(ititem))) + -- We don't want to take oxygen out of our diving suit to load our plasma cutter + -- Most loadable items have 1 capacity + -- But some have 2 or 3 (coil speargun) + if itemRef and itemRef.inventory and itemRef.inventory.Capacity < 4 then + -- MyModGlobal.debugPrint(string.format("Skipping small inventory %s", tostring(itemRef.inventory))) + return false + end + -- 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.slotIndex1 - 1) + -- 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 - -- 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, true) + }) return movableBySlot end @@ -93,11 +97,11 @@ local function printPermissibleItems(movableBySlot) end ----@param slot InventorySlot +---@param invSlot InventorySlot ---@param preferMinCondition boolean -local function tryReloadSlot(slot, preferMinCondition) +local function tryReloadSlot(invSlot, preferMinCondition) ---@type Barotrauma.Item - local item = slot.slot.items[1] + local item = invSlot.item if not item then MyModGlobal.debugPrint("No item in slot") return @@ -115,13 +119,10 @@ local function tryReloadSlot(slot, preferMinCondition) MyModGlobal.debugPrint("No slots") return end - -- MyModGlobal.debugPrint("Slots:") - -- dump(slots) ---@type table local movableBySlot = getItemsPerSlot(slots) -- MyModGlobal.debugPrint("Movable by slot:") - -- dump(movableBySlot) local permissibleItems = LOAD_MAP[tostring(item.Prefab.Identifier.Value)] if not permissibleItems then @@ -156,22 +157,19 @@ local function tryReloadSlot(slot, preferMinCondition) -- We loaded as many as we have been allowed to -- And we do this check up front because an item may already -- Be partially loaded - local nowHave = #inventorySlot.slot.items + local nowHave = inventorySlot.stackSize if nowHave >= permissible then - -- MyModGlobal.debugPrint(string.format( - -- "Finished processing item: %s. Current slot has reached the permissible limit of %d items.", - -- tostring(ititem.Prefab.Identifier.Value), permissible)) + MyModGlobal.debugPrint(string.format( + "Finished processing item: %s. Current slot has reached the permissible limit of %d items.", + tostring(ititem.Prefab.Identifier.Value), permissible)) break end - local moved = inventorySlot.inventory.TryPutItem(ititem, inventorySlot.slotIndex, false, true, Character.Controlled, true) - -- When the slot is full no more will be able to be moved - -- And tat that point we're done with that slot - if not moved then break end + if not inventorySlot:canFit(ititem.Prefab) then + break + end + utils.enqueueMove(ititem, inventorySlot) numMoved = numMoved + 1 - - -- else - -- MyModGlobal.debugPrint(string.format("Not permissible: %s", tostring(ititem.Prefab.Identifier.Value))) end end end diff --git a/CykaQuick/Lua/Cyka/utils.lua b/CykaQuick/Lua/Cyka/utils.lua index d3d8826..3c6b106 100644 --- a/CykaQuick/Lua/Cyka/utils.lua +++ b/CykaQuick/Lua/Cyka/utils.lua @@ -143,21 +143,14 @@ MyModGlobal.InventorySlot = { howManyCanFit = function(self, itemPrefab) -- There is an item in the slot and it's not stackable with itemPrefab if self.item and not self.item.Prefab.Equals(itemPrefab) then - MyModGlobal.debugPrint(string.format( - "%s can fit 0 of %s because it already contains an item that is not stackable with %s (%s)", - tostring(self), tostring(itemPrefab), tostring(itemPrefab), tostring(self.item.Prefab))) return 0 end -- The slot is empty - we can fit as many as the game tells us if not self.item then - MyModGlobal.debugPrint(string.format("%s can fit %d of %s because it is empty", tostring(self), - itemPrefab.GetMaxStackSize(self.inventory), tostring(itemPrefab))) return itemPrefab.GetMaxStackSize(self.inventory) end -- The slot has an item that is stackable with itemPrefab -- We can fit as many as to fill the stack - MyModGlobal.debugPrint(string.format("%s can fit %d of %s because it contains %d items", tostring(self), - self.maxStackSize - self.stackSize, tostring(itemPrefab), self.stackSize)) return self.maxStackSize - self.stackSize end, ---@param self InventorySlot @@ -281,7 +274,7 @@ local function ensureOptionsDefaults(options) options.slotPredicate = options.slotPredicate or function() return true end options.inventoryPredicate = options.inventoryPredicate or function() return true end options.loadRefs = options.loadRefs == true - options.itemRef = options.itemRef or nil + options.itemRef = options.itemRef or {} options.recurse = options.recurse == true return options end @@ -417,17 +410,19 @@ do if not inventory then return options, "No inventory" end options.loadRefs = true + local originalItemPredicate = options.itemPredicate or function() return true end options.itemPredicate = function(item) if not item then return false end local parentInventory = item.ParentInventory if not parentInventory then return false end if not parentInventory.Equals(inventory) then return false end - return true + return originalItemPredicate(item, options.itemRef) end + local originalSlotPredicate = options.slotPredicate or function() return true end options.slotPredicate = function(slot, itemRef) if not slot then return false end if itemRef.slotIndex1 and relevantPlayerInventorySlots[itemRef.slotIndex1] then - return true + return originalSlotPredicate(slot, itemRef) end return false end