Refactor quickreload

This commit is contained in:
2025-03-30 21:27:50 +02:00
parent 407a7d27a1
commit c5ea3bc2aa

View File

@@ -3,24 +3,77 @@ local cursormacroer = require("Cyka.cursormacroer")
local utils = require("Cyka.utils")
local dump = require("Cyka.dump")
---@param inventory Barotrauma.ItemInventory
---@param predicate fun(slot: InventorySlot): boolean
---@return InventorySlot[], string?
local function findSlotsThat(inventory, predicate)
local slots = {}
for i, slot in ipairs(inventory.slots) do
local inventorySlot = {
slot = slot,
inventory = inventory,
slotIndex = i - 1
-- 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<string, table<string, boolean>>
local LOAD_MAP = {
}
---@param inventory Barotrauma.ItemInventory
---@return InventorySlot[]
local function getSlots(inventory)
local slots = {}
local inventorySlots = inventory.slots
for i, inventorySlot in ipairs(inventorySlots) do
slots[#slots + 1] = {
inventory = inventory,
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<InventorySlot, Barotrauma.Item[]>
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<InventorySlot, Barotrauma.Item[]>
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<InventorySlot, Barotrauma.Item[]>
---@return table<InventorySlot, table<Barotrauma.ItemPrefab, boolean>>
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<InventorySlot, table<Barotrauma.ItemPrefab, boolean>>
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<InventorySlot, Barotrauma.Item[]>
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<InventorySlot, Barotrauma.ItemPrefab>
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
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
permissibleItemsPerSlot[inventorySlot] = thisone
end
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