storage-solution/src/modules/inv.lua
2025-11-11 21:48:01 +02:00

210 lines
5 KiB
Lua

local previousInventory = {}
---@type ccTweaked.peripheral.WiredModem
local modem = peripheral.find("modem");
local turtleId = modem.getNameLocal()
local turtleMoveAllowed = true
local config = require("../../config") ---@type Config
local abstractInventoryLib = require("lib.abstractInventoryLib")
local peripherals = peripheral.getNames();
---@type AbstractInventory
local ail = nil
local function sync()
print("Syncing..")
---@type string[]
local foundInventories = {}
for _, invPattern in ipairs(config.inventories) do
for _, inv in ipairs(peripherals) do
if string.find(inv, invPattern) then
table.insert(foundInventories, inv)
end
end
end
ail = abstractInventoryLib(foundInventories, true, {
--[[cache = true,
optimal = true,
unoptimal = true,
api = true,
defrag = true,
redirect = function (e)
print(e)
end,]]
})
print("Synced.");
end
---@param itemName string
---@param perip ccTweaked.peripheral.Inventory|string|nil
---@param maxAmount number|nil
local function sendItemToSelf(itemName, perip, maxAmount)
if perip == nil then
perip = turtleId
end
turtleMoveAllowed = false
local remaining = maxAmount or 64
local total = 0
if remaining <= 0 then
turtleMoveAllowed = true
return
end
if ail.getItem(itemName) then
local nbtList = ail.listNBT(itemName)
local chosenNBT = nil
if nbtList and #nbtList > 0 then
chosenNBT = nbtList[math.random(1, #nbtList)]
end
if chosenNBT == "NONE" then
chosenNBT = nil
end
while remaining > 0 do
local toSend = math.min(64, remaining)
local ok, moved = pcall(function()
ail.performTransfer()
local amount = ail.pushItems(perip, itemName, toSend, nil, chosenNBT, {
["allowBadTransfers"] = true,
["optimal"] = false
})
ail.performTransfer()
return amount
end)
total = total + moved
if ok and moved and moved > 0 then
remaining = remaining - moved
else
break
end
end
end
-- sleep(0.1)
turtleMoveAllowed = true
return total
end
---@param slots ccTweaked.turtle.turtleSlot[]
---@param perip ccTweaked.peripheral.Inventory|nil
---@param id string|nil
---@param maxAmount number|nil
local function sendItemAwayMultiple(slots, perip, id, maxAmount)
if perip == nil then
perip = turtle
end
local srcId = id or turtleId
if srcId == nil then return end
local itemsInSlots = {}
for _, slot in ipairs(slots) do
local item = perip.getItemDetail(slot)
if item then
itemsInSlots[slot] = item
end
end
local totalMoved = 0
local remaining = maxAmount or math.huge
if remaining <= 0 then
return 0
end
for _, slot in ipairs(slots) do
if remaining <= 0 then break end
local toSend = math.min(64, remaining)
local ok, pulled = pcall(function()
ail.performTransfer()
local moved = ail.pullItems(srcId, slot, toSend, nil, nil, {
["allowBadTransfers"] = true,
["optimal"] = false
})
ail.performTransfer()
return moved
end)
if ok and pulled and pulled > 0 then
totalMoved = totalMoved + pulled
remaining = remaining - pulled
end
end
local numItems = 0
for _, _ in pairs(itemsInSlots) do
numItems = numItems + 1
end
if numItems > 0 then
os.queueEvent("update_ui")
end
return totalMoved
end
local function getTurtleInventory()
local inventory = {}
for slot = 1, 16 do
local item = turtle.getItemDetail(slot, false)
inventory[slot] = item
end
return inventory
end
local function detectPlayerInsert()
previousInventory = getTurtleInventory()
while true do
os.pullEvent("turtle_inventory")
local currentInventory = getTurtleInventory()
if turtleMoveAllowed then
local newlyAddedSlots = {}
for slot = 1, 16 do
local prev = previousInventory[slot]
local curr = currentInventory[slot]
if not prev and curr then
table.insert(newlyAddedSlots, slot)
end
end
if #newlyAddedSlots > 0 then
sendItemAwayMultiple(newlyAddedSlots)
end
end
previousInventory = currentInventory
end
end
local function getAIL()
return ail
end
return {
detectPlayerInsert = detectPlayerInsert,
sendItemAwayMultiple = sendItemAwayMultiple,
sendItemToSelf = sendItemToSelf,
getTurtleInventory = getTurtleInventory,
sync = sync,
getAIL = getAIL,
}