cc-automation/localchest.lua
2025-05-15 18:03:59 +02:00

149 lines
3.3 KiB
Lua

local itemstack = require("itemstack")
local localchest = {}
local prototype = {}
function prototype:exists()
return self.peripheral.size() ~= nil
end
function prototype:scanSlot(slot)
local stack = itemstack.fromItemDetail(self.peripheral.getItemDetail(slot), self.peripheral.getItemLimit(slot))
self.slots[slot] = stack
return stack
end
function prototype:rescan()
if not self:exists() then
return false
end
self.slots = {}
self.size = self.peripheral.size()
for key,_ in pairs(self.peripheral.list()) do
self:scanSlot(key)
end
return true
end
function prototype:sanityCheck()
if not self:exists() then
return false
end
local listData = self.peripheral.list()
for key,_ in pairs(self.slots) do
if listData[key] == nil then
return false
end
end
for key,stackData in pairs(listData) do
local cachedStack = self.slots[key]
if cachedStack == nil or cachedStack.item.name ~= stackData.name or cachedStack.count ~= stackData.count then
return false
end
end
return true
end
function prototype:getSlot(slot)
local stack = self.slots[slot]
if stack == nil then
return itemstack.blank(self.peripheral.getItemLimit(slot))
end
return stack
end
function prototype:moveItemsTo(count, fromSlot, otherChest, toSlot)
if not otherChest:exists() then
return 0
end
local myStack = self:getSlot(fromSlot)
local targetStack = otherChest:getSlot(toSlot)
local txCap = myStack:canTransferTo(targetStack)
if count > txCap then
return 0
end
local tx = self.peripheral.pushItems(peripheral.getName(otherChest.peripheral), fromSlot, count, toSlot)
myStack.count = myStack.count - tx
if myStack.count == 0 then
self.slots[fromSlot] = nil
end
targetStack.count = targetStack.count + tx
if targetStack:isBlank() then
targetStack.item = myStack.item
otherChest.slots[toSlot] = targetStack
end
return tx
end
function prototype:getIdentifier()
return peripheral.getName(self.peripheral)
end
local metatable = {
__index = prototype,
__tostring = function(ser)
local slots = {}
for key,value in pairs(ser.slots) do
slots[key] = tostring(value)
end
return textutils.serialise({
peripheral = peripheral.getName(ser.peripheral),
slots = slots,
size = ser.size
}, { compact = true })
end
}
function localchest.fromPeripheral(per)
if type(per) == "string" then
per = peripheral.wrap(per)
end
local chest = {
peripheral = per,
slots = {},
size = 0
}
setmetatable(chest, metatable)
return chest
end
function localchest.fromString(str)
local chest = textutils.unserialize(str)
if type(chest.peripheral) ~= "string" or
type(chest.slots) ~= "table" or
type(chest.size) ~= "number" then
error("Could not parse localchest: "..str)
end
local per = peripheral.wrap(chest.peripheral)
if per == nil then
error("Could not wrap peripheral for chest: "..chest.peripheral)
end
chest.peripheral = per
for key,value in pairs(chest.slots) do
chest.slots[key] = itemstack.fromString(value)
end
setmetatable(chest, metatable)
return chest
end
return localchest