Refactor a bunch of shit to utils

This commit is contained in:
2025-03-30 22:54:42 +02:00
parent 3339925990
commit 7bee770482
5 changed files with 248 additions and 28 deletions

View File

@@ -65,11 +65,6 @@ local function getMouseoverSlots(inventory, slots, depth)
return slots, nil
end
---@class InventorySlot
---@field inventory Barotrauma.Inventory
---@field slotIndex number
---@field slot Barotrauma.Inventory.ItemSlot
---@return InventorySlot[], string?
local function getInventorySlotsUnderCursor()
-- Make sure we have a controlled character

View File

@@ -35,12 +35,12 @@ local function getItemsPerSlot(from, slots)
---@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, inventoryRef)
utils.enqueueInventory(from, {}, 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 inventoryRef and inventoryRef.Capacity < 4 then
-- MyModGlobal.debugPrint(string.format("Skipping small inventory %s", tostring(inventoryRef)))
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:")

View File

@@ -189,9 +189,6 @@ local function tryMoveItems(items, itemTree, force)
end
-- This is a bit fucking sucky.....
-- But I really don't know better
-- Maybe it will be fine...
---@return Barotrauma.Item[]
local function getOpenContainers()
-- MyModGlobal.debugPrint("Attempting to find open container...")

View File

@@ -2,11 +2,6 @@
local cursormacroer = require("Cyka.cursormacroer")
local dump = require("Cyka.dump")
---@class InventorySlot
---@field slot Barotrauma.ItemSlot
---@field inventory Barotrauma.ItemInventory
---@field slotIndex number
---@param inventory Barotrauma.ItemInventory
---@param predicate fun(slot: InventorySlot): boolean
---@return InventorySlot[], string?

View File

@@ -1,3 +1,16 @@
-- luacheck: globals Character MyModGlobal
-- luacheck: max line length 420
---@class ItemRefs
---@field item Barotrauma.Item
---@field inventory Barotrauma.ItemInventory
---@field slot Barotrauma.ItemInventory.Slot
---@class InventorySlot
---@field slot Barotrauma.ItemSlot
---@field inventory Barotrauma.ItemInventory
---@field slotIndex number
-- We got to do this shit because enqueueInventory calls enqueueItem
-- And enqueueItem calls enqueueInventory
-- So unless we define them both before using them
@@ -5,6 +18,9 @@
local enqueueItem
local enqueueSlot
local enqueueInventory
local allPlayerItems
local allSubmarineItems
local allOwnedItems
local _
---@alias FilterPredicate fun(item: Barotrauma.Item, inventoryRef?: Barotrauma.ItemInventory, slotRef: Barotrauma.ItemInventory.Slot): boolean
@@ -15,19 +31,19 @@ local _
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@param loadRefs? boolean
---@param slotRef? Barotrauma.ItemInventory.Slot
---@param inventoryRef? Barotrauma.ItemInventory
---@param itemRef? ItemRefs
---@return Barotrauma.Item[], string?
enqueueItem = function(item, queue, predicate, loadRefs, inventoryRef, slotRef)
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, inventoryRef, slotRef)
local ok, stop = predicate(item, itemRef)
if ok then
queue[#queue + 1] = item
end
@@ -38,9 +54,10 @@ enqueueItem = function(item, queue, predicate, loadRefs, inventoryRef, slotRef)
-- So inventrorY should be fine here
-- debugPrint("Item has its own inventory, enqueuing inventory...")
if loadRefs then
queue, _ = enqueueInventory(item.OwnInventory, queue, predicate, loadRefs)
itemRef.item = item
queue, _ = enqueueInventory(item.OwnInventory, queue, predicate, loadRefs, itemRef)
else
queue, _ = enqueueInventory(item.OwnInventory, queue, predicate)
queue, _ = enqueueInventory(item.OwnInventory, queue, predicate, itemRef)
end
-- if err then
-- debugPrint(string.format("Error enqueuing inventory: %s", err))
@@ -54,11 +71,12 @@ end
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@param loadRefs? boolean
---@param inventoryRef? Barotrauma.ItemInventory
---@param itemRef? ItemRefs
---@return Barotrauma.Item[], string?
enqueueSlot = function(slot, queue, predicate, loadRefs, inventoryRef)
enqueueSlot = function(slot, queue, predicate, loadRefs, itemRef)
queue = queue or {}
predicate = predicate or function() return true end
itemRef = itemRef or {}
-- debugPrint(string.format("Enqueuing slot with %d items.", #slot.items))
-- We don't want to shadow queue
local err
@@ -70,7 +88,8 @@ enqueueSlot = function(slot, queue, predicate, loadRefs, inventoryRef)
for _, item in ipairs(slot.items) do
-- Only the final leaf nodes decide upon the predicate
if loadRefs then
queue, err = enqueueItem(item, queue, predicate, loadRefs, inventoryRef, slot)
itemRef.slot = slot
queue, err = enqueueItem(item, queue, predicate, loadRefs, itemRef)
else
queue, err = enqueueItem(item, queue, predicate)
end
@@ -86,10 +105,12 @@ end
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@param loadRefs? boolean
---@param itemRef? ItemRefs
---@return Barotrauma.Item[], string?
enqueueInventory = function(inventory, queue, predicate, loadRefs)
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
if not inventory then return queue, "No inventory" end
@@ -98,7 +119,8 @@ enqueueInventory = function(inventory, queue, predicate, loadRefs)
for _, slot in ipairs(inventory.slots) do
-- Only the final leaf nodes decide upon the predicate
if loadRefs then
queue, err = enqueueSlot(slot, queue, predicate, loadRefs, inventory)
itemRef.inventory = inventory
queue, err = enqueueSlot(slot, queue, predicate, loadRefs, itemRef)
else
queue, err = enqueueSlot(slot, queue, predicate)
end
@@ -110,8 +132,219 @@ enqueueInventory = function(inventory, queue, predicate, loadRefs)
return queue
end
local relevantPlayerInventorySlots = { 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, MyModGlobal.BAG_SLOT }
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@param loadRefs? boolean
---@return Barotrauma.Item[], string?
allPlayerItems = function(queue, predicate, loadRefs)
queue = queue or {}
predicate = predicate or function() return true end
local character = Character.Controlled
if not character then return queue, "No character" end
local inventory = character.Inventory
if not inventory then return queue, "No inventory" end
for _, slotid in ipairs(relevantPlayerInventorySlots) do
local slot = inventory.slots[slotid]
local err
if not slot then goto continue end
if #slot.items == 0 then goto continue end
queue, err = enqueueSlot(slot, queue, predicate, loadRefs)
if err then return queue, err end
::continue::
end
return queue
end
---@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
-- Even if its empty
local itemRef = {}
local character = Character.Controlled
if not character then return queue, "No character" end
local submarine = character.Submarine
if not submarine then return queue, "No submarine" end
for item in submarine.GetItems(false) do
-- We do NOT want to call enqueueItem here because enqueueItem
-- Is recursive
-- And this call (GetItems) already gets all items
-- So we would be doing double the work (at best case)
-- It also means we won't have refs here which sucks
local ok, stop = predicate(item, itemRef)
if ok then
queue[#queue + 1] = item
end
if stop then return queue, "Stop" end
end
return queue
end
---@param queue Barotrauma.Item[]
---@param predicate? FilterPredicate
---@param loadRefs? boolean
---@return Barotrauma.Item[], string?
allOwnedItems = function(queue, predicate, loadRefs)
queue = queue or {}
predicate = predicate or function() return true end
local err
queue, err = allPlayerItems(queue, predicate, loadRefs)
if err then return queue, err end
queue, err = allSubmarineItems(queue, predicate)
if err then return queue, err end
return queue
end
---@return Barotrauma.Item[], string?
local function getOpenContainers()
local controlledCharacter = Character.Controlled
if not controlledCharacter then return {}, "No controlled character" end
local selectedItem = controlledCharacter.SelectedItem
if not selectedItem then return {}, "No selected item" end
return { selectedItem }, nil
end
---@return Barotrauma.Item, string?
local function getFirstOpenContainer()
local containers, err = getOpenContainers()
if err then return nil, err end
if #containers == 0 then return nil, "No open containers" end
return containers[1], nil
end
-- 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 InventorySlot[]
---@param depth number
---@return InventorySlot[], 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] = {
inventory = inventory,
slotIndex = i,
slot = slot
}
end
::continue::
end
return slots, nil
end
---@return InventorySlot[], string?
local function getSlotsUnderCursor()
-- Make sure we have a controlled character
local controlledCharacter = Character.Controlled
if not controlledCharacter then return nil, "No controlled character" end
local inventory = controlledCharacter.Inventory
if not inventory then return nil, "No inventory" end
local mouseoverSlots, err = getMouseoverSlots(inventory)
if err then return mouseoverSlots, err end
-- Even if we don't get them we're still fine
local openContainers, _ = getOpenContainers()
-- if err then return mouseoverSlots, err end
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 = containerInventory.slots[i]
mouseoverSlots[#mouseoverSlots + 1] = {
inventory = containerInventory,
slotIndex = i,
slot = slot
}
end
end
end
end
return mouseoverSlots, nil
end
---@return InventorySlot, string?
local function getFirstSlotUnderCursor()
local slots, err = getSlotsUnderCursor()
if err then return nil, err end
if #slots == 0 then return nil, "No slots found under cursor" end
return slots[1], nil
end
return {
enqueueItem = enqueueItem,
enqueueSlot = enqueueSlot,
enqueueInventory = enqueueInventory
enqueueInventory = enqueueInventory,
enqueueAllPlayerItems = allPlayerItems,
enqueueAllSubmarineItems = allSubmarineItems,
enqueueAllOwnedItems = allOwnedItems,
getOpenContainers = getOpenContainers,
getFirstOpenContainer = getFirstOpenContainer,
getSlotsUnderCursor = getSlotsUnderCursor,
getFirstSlotUnderCursor = getFirstSlotUnderCursor,
}