Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ChestManager = { chests = {}, itemList = {} }
- Chest = { name = "", id = -1, itemList = {}, wrap = nil, maxslots = 0 }
- function ChestManager:new(o)
- o = o or {}
- setmetatable(o, self)
- self.__index = self
- return o
- end
- function ChestManager:findChests()
- local pNames = peripheral.getNames()
- for i = 2, #pNames do
- local chest = Chest:new{name = pNames[i], id = tonumber(string.sub(pNames[i], 23))}
- chest:connect()
- chest:init()
- self:addChest(chest)
- end
- end
- function ChestManager:mergeItemList()
- for _, chest in pairs(self.chests) do
- for itemName, item in SortedPairs(chest.itemList) do
- if self.itemList[itemName] == nil then
- self.itemList[itemName] = { itemCount = 0 }
- end
- if self.itemList[itemName][chest.name] == nil then
- self.itemList[itemName][chest.name] = item.slot
- else
- table.insert(self.itemList[itemName][chest.name], item.slot)
- end
- self.itemList[itemName].itemCount = self.itemList[itemName].itemCount + item.itemCount
- end
- end
- end
- function ChestManager:findFreeSlot()
- local slot = -1
- for i, chest in SortedPairs(self.chests, function(a, b, tab) return tab[a].id < tab[b].id end) do
- slot = chest:findFreeSlot()
- if slot ~= -1 then
- return { slot = slot, name = chest.name }
- end
- end
- return -1
- end
- function ChestManager:sort()
- local keys = SortedPairsKeys(self.itemList)
- local chests = SortedPairsKeys(self.chests, function(a, b, tab) return tab[a].id < tab[b].id end)
- local incremented = false
- local j = 1
- local k = 1
- local chest = nil
- while k ~= #chests and j ~= (#keys + 1) do
- local slotN = 1
- print("Moving " .. keys[j] )
- for name, slots in pairs(self.itemList[keys[j]]) do
- chest = self.chests[chests[k]]
- if name ~= "itemCount" then
- -- print(textutils.serialise(self.itemList[keys[j]]))
- -- print(name)
- -- print(chest.name)
- if chest.name ~= name then
- for i, slot in pairs(slots) do
- if (chest.wrap.getItemDetail(slotN) ~= nil) and (chest.wrap.getItemDetail(slotN).name ~= keys[j]) then
- local freeSlot = self:findFreeSlot()
- local retry = true
- while true do
- if freeSlot ~= -1 then
- print("SlotN " .. slotN .. " occupied by " .. chest.wrap.getItemDetail(slotN).name .. " moving to " .. freeSlot.slot .. " at " .. freeSlot.name )
- chest:moveFromSlotToOtherSlot(freeSlot.name, slotN, freeSlot.slot)
- break
- else
- if retry == false then
- print("Can't find freeslot!")
- return
- end
- print("Freeslot didn't work sorting")
- chest:sort()
- retry = false
- end
- end
- end
- chest:moveFromSlotToOtherSlot(name, slot, slotN, true)
- slotN = slotN + 1
- end
- end
- end
- end
- chest:init()
- self.itemList = {}
- self:mergeItemList()
- j = j + 1
- end
- chest:sort()
- end
- function ChestManager:printItem(name)
- print(("Item %s: %s"):format(name, textutils.serialise(self.itemList[name])))
- end
- function ChestManager:printChests()
- local printString = ""
- for k, v in pairs(self.chests) do
- printString = printString .. ("New chest %s\n"):format(v.name) .. ("ItemList %s\n"):format(textutils.serialise(v.itemList)) .. ("MaxSlot %d\n"):format(v.maxslots)
- end
- textutils.pagedPrint(printString)
- end
- function ChestManager:printNames()
- for i, chest in SortedPairs(self.chests, function(a, b, tab) return tab[a].id < tab[b].id end) do
- print(chest.name)
- end
- end
- function ChestManager:printItems()
- local printString = ""
- for k, v in SortedPairs(self.itemList) do
- printString = printString .. ("Item %s: %s"):format(k, textutils.serialise(v))
- end
- textutils.pagedPrint(printString)
- end
- function ChestManager:addChest(chest)
- table.insert(self.chests, chest)
- end
- function Chest:new(o, name)
- o = o or {}
- setmetatable(o, self)
- self.__index = self
- self.name = name or ""
- return o
- end
- function Chest:init()
- self.itemList = {}
- for slot, item in pairs(self.wrap.list()) do
- --print(("%s:%d in slot %d"):format(item.name, item.count, slot))
- if self.itemList[item.name] == nil then
- self.itemList[item.name] = { slot = { slot }, itemCount = item.count }
- else
- table.insert(self.itemList[item.name]["slot"], slot)
- self.itemList[item.name].itemCount = self.itemList[item.name].itemCount + item.count
- end
- end
- self.maxslots = self.wrap.size()
- end
- function Chest:connect()
- self.wrap = peripheral.wrap(self.name)
- end
- function Chest:print()
- for k, v in SortedPairs(self.itemList) do
- textutils.pagedPrint(("%s : %d"):format(k, v.itemCount))
- end
- end
- function Chest:printItem(name, paged)
- paged = paged or false
- if paged then
- textutils.pagedPrint(("Item %s => %s"):format(name, textutils.serialise(self.itemList[name])))
- else
- print(("Item %s => %s"):format(name, textutils.serialise(self.itemList[name])))
- end
- end
- function Chest:findFreeSlot()
- local slot = 0
- for i, k in ipairs(self.wrap.list()) do
- slot = i
- end
- if (slot + 1) < self.maxslots then
- slot = slot + 1
- else
- slot = -1
- end
- return slot
- end
- function Chest:moveFromSlotToOtherSlot(name, slot1, slot2, pull)
- pull = pull or false
- if name == self.name then
- local namez = self.wrap.getItemDetail(slot1).name
- local key = self:findKeyFromValueItem(namez, slot1)
- self.itemList[namez].slot[key] = slot2
- end
- if pull then
- return self.wrap.pullItems(name, slot1, 64, slot2)
- else
- return self.wrap.pushItems(name, slot1, 64, slot2)
- end
- end
- function Chest:moveFromSlotToSlot(slot1, slot2)
- return self:moveFromSlotToOtherSlot(self.name, slot1, slot2)
- end
- function SortedPairsKeys(tab, sort)
- sort = sort or function(a, b, tab) return tab[a].itemCount > tab[b].itemCount end
- local keys = {}
- for k in pairs(tab) do
- keys[#keys + 1] = k
- end
- table.sort(keys, function(a, b) return sort(a, b, tab) end)
- return keys
- end
- function SortedPairs(tab, sort)
- local keys = {}
- keys = SortedPairsKeys(tab, sort)
- local j = 0
- return
- function()
- j = j + 1
- local k = keys[j]
- if k ~= nil then
- return k, tab[k]
- end
- end
- end
- function Chest:findKeyFromValueItem(itemName, value)
- for k,v in pairs(self.itemList[itemName].slot) do
- if v==value then return k end
- end
- return nil
- end
- function Chest:sort()
- local slotN = 1
- local stop = false
- for itemName, _ in SortedPairs(self.itemList) do
- local item = self.itemList[itemName]
- local increased = false
- if stop or (slotN > self.maxslots) then
- break
- end
- for key, _ in pairs(item.slot) do
- local itemSlot = item.slot[key]
- local freeSlot = self:findFreeSlot()
- increased = false
- if freeSlot == -1 then
- print("Can't sort without at least one free slot!")
- stop = true
- break
- end
- if (itemSlot ~= slotN) then
- if (self.wrap.getItemDetail(slotN) ~= nil) and (self.wrap.getItemDetail(slotN).name ~= itemName) then
- self:moveFromSlotToSlot(slotN, freeSlot)
- end
- self:moveFromSlotToSlot(itemSlot, slotN)
- if (self.wrap.getItemDetail(itemSlot) ~= nil) then
- table.insert(item.slot, itemSlot)
- end
- end
- if self.wrap.getItemDetail(slotN).count >= self.wrap.getItemDetail(slotN).maxCount then
- slotN = slotN + 1
- increased = true
- end
- end
- if increased == false then
- slotN = slotN + 1
- end
- self:init()
- end
- end
- return { ChestManager = ChestManager }
Add Comment
Please, Sign In to add comment