alsacchi

chest.lua

Jan 31st, 2022 (edited)
991
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.89 KB | None | 0 0
  1. ChestManager = { chests = {}, itemList = {} }
  2. Chest = { name = "", id = -1, itemList = {}, wrap = nil, maxslots = 0 }
  3.  
  4. function ChestManager:new(o)
  5.     o = o or {}
  6.     setmetatable(o, self)
  7.     self.__index = self
  8.     return o
  9.  end
  10.  
  11. function ChestManager:findChests()
  12.     local pNames = peripheral.getNames()
  13.     for i = 2, #pNames do
  14.         local chest = Chest:new{name = pNames[i], id = tonumber(string.sub(pNames[i], 23))}
  15.         chest:connect()
  16.         chest:init()
  17.         self:addChest(chest)
  18.     end
  19. end
  20.  
  21. function ChestManager:mergeItemList()
  22.     for _, chest in pairs(self.chests) do
  23.         for itemName, item in SortedPairs(chest.itemList) do
  24.             if self.itemList[itemName] == nil then
  25.                 self.itemList[itemName] = { itemCount = 0 }
  26.             end
  27.             if self.itemList[itemName][chest.name] == nil then
  28.                 self.itemList[itemName][chest.name] = item.slot
  29.             else
  30.                 table.insert(self.itemList[itemName][chest.name], item.slot)
  31.             end
  32.             self.itemList[itemName].itemCount = self.itemList[itemName].itemCount + item.itemCount
  33.         end
  34.     end
  35. end
  36.  
  37. function ChestManager:findFreeSlot()
  38.     local slot = -1
  39.     for i, chest in SortedPairs(self.chests, function(a, b, tab) return tab[a].id < tab[b].id end) do
  40.        slot = chest:findFreeSlot()
  41.        if slot ~= -1 then
  42.            return { slot = slot, name = chest.name }
  43.        end
  44.     end
  45.     return -1
  46. end
  47. function ChestManager:sort()
  48.     local keys = SortedPairsKeys(self.itemList)
  49.     local chests = SortedPairsKeys(self.chests, function(a, b, tab) return tab[a].id < tab[b].id end)
  50.     local incremented = false
  51.     local j = 1
  52.     local k = 1
  53.     local chest = nil
  54.     while k ~= #chests and j ~= (#keys + 1) do
  55.         local slotN = 1
  56.         print("Moving " .. keys[j] )
  57.  
  58.         for name, slots in pairs(self.itemList[keys[j]]) do
  59.             chest = self.chests[chests[k]]
  60.             if name ~= "itemCount" then
  61.                 -- print(textutils.serialise(self.itemList[keys[j]]))
  62.                 -- print(name)
  63.                 -- print(chest.name)
  64.                 if chest.name ~= name then
  65.                     for i, slot in pairs(slots) do
  66.                         if (chest.wrap.getItemDetail(slotN) ~= nil) and (chest.wrap.getItemDetail(slotN).name ~= keys[j]) then
  67.                             local freeSlot = self:findFreeSlot()
  68.                             local retry = true
  69.                             while true do
  70.                                 if freeSlot ~= -1 then
  71.                                     print("SlotN " .. slotN .. " occupied by " .. chest.wrap.getItemDetail(slotN).name .. " moving to " .. freeSlot.slot .. " at " .. freeSlot.name )
  72.                                     chest:moveFromSlotToOtherSlot(freeSlot.name, slotN, freeSlot.slot)
  73.                                     break
  74.                                 else
  75.                                     if retry == false then
  76.                                         print("Can't find freeslot!")
  77.                                         return
  78.                                     end
  79.                                     print("Freeslot didn't work sorting")
  80.                                     chest:sort()
  81.                                     retry = false
  82.                                 end
  83.                             end
  84.                         end
  85.                         chest:moveFromSlotToOtherSlot(name, slot, slotN, true)
  86.                         slotN = slotN + 1
  87.                     end
  88.                 end
  89.             end
  90.         end
  91.         chest:init()
  92.         self.itemList = {}
  93.         self:mergeItemList()
  94.         j = j + 1
  95.     end
  96.     chest:sort()
  97. end
  98.  
  99. function ChestManager:printItem(name)
  100.     print(("Item %s: %s"):format(name, textutils.serialise(self.itemList[name])))
  101. end
  102.  
  103. function ChestManager:printChests()
  104.     local printString = ""
  105.     for k, v in pairs(self.chests) do
  106.         printString = printString .. ("New chest %s\n"):format(v.name) .. ("ItemList %s\n"):format(textutils.serialise(v.itemList)) .. ("MaxSlot %d\n"):format(v.maxslots)
  107.     end
  108.     textutils.pagedPrint(printString)
  109. end
  110.  
  111. function ChestManager:printNames()
  112.     for i, chest in SortedPairs(self.chests, function(a, b, tab) return tab[a].id < tab[b].id end) do
  113.         print(chest.name)
  114.     end
  115. end
  116.  
  117. function ChestManager:printItems()
  118.     local printString = ""
  119.     for k, v in SortedPairs(self.itemList) do
  120.         printString = printString .. ("Item %s: %s"):format(k, textutils.serialise(v))
  121.     end
  122.     textutils.pagedPrint(printString)
  123. end
  124.  
  125. function ChestManager:addChest(chest)
  126.     table.insert(self.chests, chest)
  127. end
  128.  
  129. function Chest:new(o, name)
  130.    o = o or {}
  131.    setmetatable(o, self)
  132.    self.__index = self
  133.    self.name = name or ""
  134.    return o
  135. end
  136.  
  137. function Chest:init()
  138.     self.itemList = {}
  139.     for slot, item in pairs(self.wrap.list()) do
  140.         --print(("%s:%d in slot %d"):format(item.name, item.count, slot))
  141.         if self.itemList[item.name] == nil then
  142.             self.itemList[item.name] = { slot = { slot }, itemCount = item.count }
  143.         else
  144.             table.insert(self.itemList[item.name]["slot"], slot)
  145.             self.itemList[item.name].itemCount = self.itemList[item.name].itemCount + item.count
  146.          end
  147.     end
  148.     self.maxslots = self.wrap.size()
  149. end
  150.  
  151. function Chest:connect()
  152.     self.wrap = peripheral.wrap(self.name)
  153. end
  154.  
  155. function Chest:print()
  156.     for k, v in SortedPairs(self.itemList) do
  157.         textutils.pagedPrint(("%s : %d"):format(k, v.itemCount))
  158.     end
  159. end
  160.  
  161. function Chest:printItem(name, paged)
  162.     paged = paged or false
  163.     if paged then
  164.         textutils.pagedPrint(("Item %s => %s"):format(name, textutils.serialise(self.itemList[name])))
  165.     else
  166.         print(("Item %s => %s"):format(name, textutils.serialise(self.itemList[name])))
  167.     end
  168. end
  169.  
  170. function Chest:findFreeSlot()
  171.     local slot = 0
  172.     for i, k in ipairs(self.wrap.list()) do
  173.         slot = i
  174.     end
  175.     if (slot + 1) < self.maxslots then
  176.         slot = slot + 1
  177.     else
  178.         slot = -1
  179.     end
  180.     return slot
  181. end
  182.  
  183. function Chest:moveFromSlotToOtherSlot(name, slot1, slot2, pull)
  184.     pull = pull or false
  185.     if name == self.name then
  186.         local namez = self.wrap.getItemDetail(slot1).name
  187.         local key = self:findKeyFromValueItem(namez, slot1)
  188.         self.itemList[namez].slot[key] = slot2
  189.     end
  190.     if pull then
  191.         return self.wrap.pullItems(name, slot1, 64, slot2)
  192.     else
  193.         return self.wrap.pushItems(name, slot1, 64, slot2)
  194.     end
  195. end
  196.  
  197. function Chest:moveFromSlotToSlot(slot1, slot2)
  198.     return self:moveFromSlotToOtherSlot(self.name, slot1, slot2)
  199. end
  200.  
  201. function SortedPairsKeys(tab, sort)
  202.     sort = sort or function(a, b, tab) return tab[a].itemCount > tab[b].itemCount end
  203.     local keys = {}
  204.     for k in pairs(tab) do
  205.         keys[#keys + 1] = k
  206.     end
  207.     table.sort(keys, function(a, b) return sort(a, b, tab) end)
  208.     return keys
  209. end
  210.  
  211. function SortedPairs(tab, sort)
  212.     local keys = {}
  213.     keys = SortedPairsKeys(tab, sort)
  214.     local j = 0
  215.     return
  216.         function()
  217.             j = j + 1
  218.             local k = keys[j]
  219.             if k ~= nil then
  220.                 return k, tab[k]
  221.         end
  222.     end
  223. end
  224.  
  225. function Chest:findKeyFromValueItem(itemName, value)
  226.     for k,v in pairs(self.itemList[itemName].slot) do
  227.         if v==value then return k end
  228.       end
  229.       return nil
  230. end
  231.  
  232. function Chest:sort()
  233.     local slotN = 1
  234.     local stop = false
  235.     for itemName, _ in SortedPairs(self.itemList) do
  236.         local item = self.itemList[itemName]
  237.         local increased = false
  238.         if stop or (slotN > self.maxslots) then
  239.             break
  240.         end
  241.         for key, _ in pairs(item.slot) do
  242.             local itemSlot = item.slot[key]
  243.             local freeSlot = self:findFreeSlot()
  244.             increased = false
  245.             if freeSlot == -1 then
  246.                 print("Can't sort without at least one free slot!")
  247.                 stop = true
  248.                 break
  249.             end
  250.             if (itemSlot ~= slotN) then
  251.                 if (self.wrap.getItemDetail(slotN) ~= nil) and (self.wrap.getItemDetail(slotN).name ~= itemName) then
  252.                     self:moveFromSlotToSlot(slotN, freeSlot)
  253.                 end
  254.                 self:moveFromSlotToSlot(itemSlot, slotN)
  255.                 if (self.wrap.getItemDetail(itemSlot) ~= nil) then
  256.                     table.insert(item.slot, itemSlot)
  257.                 end
  258.             end
  259.            
  260.             if self.wrap.getItemDetail(slotN).count >= self.wrap.getItemDetail(slotN).maxCount then
  261.                 slotN = slotN + 1
  262.                 increased = true
  263.             end
  264.  
  265.         end
  266.         if increased == false then
  267.             slotN = slotN + 1
  268.         end
  269.         self:init()
  270.     end
  271. end
  272.  
  273. return { ChestManager = ChestManager }
Add Comment
Please, Sign In to add comment