AdditionalPylons

limapi

Mar 29th, 2025 (edited)
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.12 KB | None | 0 0
  1. local cache = {} -- {["item:id"] = {["periph:id"] = {slot_n,slot_m...}}}
  2. local mainChest = nil
  3. local periphs = {} -- {["periph:id"] = true}
  4. local debug = false
  5.  
  6. local function registerChests()
  7.     periphs = {}
  8.     local names = peripheral.getNames()
  9.    
  10.     for i = 1, #names do
  11.         local name = names[i]
  12.         if peripheral.hasType(name,"inventory") and name ~= mainChest then
  13.             periphs[name] = true
  14.         end
  15.     end
  16. end
  17. local function loadCache(file)
  18.     local f = fs.open(file,"r")
  19.     if f == nil then return end
  20.     cache = textutils.unserialise(f.readAll())
  21.     f.close()
  22. end
  23. local function saveCache(file)
  24.     local f = fs.open(file,"w")
  25.     f.write(textutils.serialise(cache))
  26.     f.close()
  27. end
  28. local function createCache()
  29.     cache = {}
  30.     for i in pairs(periphs) do
  31.         if i ~= mainChest then
  32.             local items = peripheral.call(i, "list")
  33.             for slot, item in pairs(items) do
  34.                 cache[item.name] = cache[item.name] or {}
  35.                 cache[item.name][i] = cache[item.name][i] or {}
  36.                 cache[item.name][i][slot] = true
  37.             end
  38.         end
  39.     end
  40. end
  41. local function setMainChest(name)
  42.     if mainChest~=nil then periphs[mainChest]=true end
  43.     mainChest = name
  44.     periphs[name]=nil
  45. end
  46.  
  47. local function pullItem(item, count)
  48.     if item=="" or count==0 or cache[item]==nil then return 0 end
  49.     local main = peripheral.wrap(mainChest)
  50.     local remaining = count
  51.    
  52.     for periphName,slots in pairs(cache[item]) do
  53.         local items = peripheral.call(periphName, "list")
  54.         for slot in pairs(slots) do
  55.             if slot == nil then break end
  56.             if items[slot].count <= remaining then
  57.                 cache[item][periphName][slot]=nil
  58.                 local next = next
  59.                 if next(cache[item][periphName]) == nil then
  60.                     cache[item][periphName] = nil
  61.                     if next(cache[item]) == nil then
  62.                         cache[item] = nil
  63.                     end
  64.                 end
  65.             end
  66.             remaining = remaining - main.pullItems(periphName,slot,remaining)
  67.             if remaining <= 0 then return count end
  68.         end
  69.     end
  70.        
  71.     return count-remaining
  72. end
  73. local function pushItemFromSlot(slot,item,count)
  74.     -- this is a helper function and will do nothing if cached slots are full
  75.     local remaining = count
  76.     local main = peripheral.wrap(mainChest)
  77.     for periphName,slots in pairs(cache[item]) do
  78.         for i in pairs(slots) do
  79.             remaining = remaining - main.pushItems(periphName,slot,remaining,i)
  80.             if remaining<=0 then return count end
  81.         end
  82.     end
  83.     return count-remaining
  84. end
  85. local function pushItem(item, count)
  86.     if item=="" or count==0 then return 0 end
  87.     local main = peripheral.wrap(mainChest)
  88.     local items = main.list()
  89.     local foundSlots = {}
  90.     local totalFound = 0
  91.     local maxSlot = 0
  92.     cache[item] = cache[item] or {}
  93.  
  94.     for slot, it in pairs(items) do
  95.         if slot > maxSlot then maxSlot = slot end
  96.         if it.name == item then
  97.             foundSlots[slot] = it.count
  98.             totalFound = totalFound + it.count
  99.         else
  100.             foundSlots[slot] = 0
  101.         end
  102.     end
  103.  
  104.     if totalFound == 0 then return 0 end
  105.     local toMove = math.min(count, totalFound)
  106.     local remaining = toMove
  107.  
  108.     local recachePeriphs = {}
  109.     local cachedPeriphs = cache[item] or {}
  110.     for periphName in pairs(cachedPeriphs) do
  111.         for slot = maxSlot, 1, -1 do
  112.             if remaining <= 0 then break end
  113.             local slotCount = foundSlots[slot] or 0
  114.             if slotCount > 0 then
  115.                 local pushed = main.pushItems(periphName, slot, remaining)
  116.                 if pushed > 0 then
  117.                     remaining = remaining - pushed
  118.                     foundSlots[slot] = foundSlots[slot] - pushed
  119.                     table.insert(recachePeriphs,periphName)
  120.                 end
  121.             end
  122.         end
  123.     end
  124.  
  125.     if remaining > 0 then
  126.         for periphName in pairs(periphs) do
  127.             if not cachedPeriphs[periphName] then
  128.                 for slot = maxSlot, 1, -1 do
  129.                     if remaining <= 0 then break end
  130.                     local slotCount = foundSlots[slot] or 0
  131.                     if slotCount > 0 then
  132.                         local pushed = main.pushItems(periphName, slot, remaining)
  133.                         if pushed > 0 then
  134.                             cache[item] = cache[item] or {}
  135.                             table.insert(recachePeriphs,periphName)
  136.                             remaining = remaining - pushed
  137.                             foundSlots[slot] = foundSlots[slot] - pushed
  138.                         end
  139.                     end
  140.                 end
  141.             end
  142.         end
  143.     end
  144.  
  145.     for i=1,#recachePeriphs do
  146.         local p = recachePeriphs[i]
  147.         local l = peripheral.call(p,"list")
  148.         for slot,it in pairs(l) do
  149.             if it.name==item then
  150.                 cache[item][p] = cache[item][p] or {}
  151.                 cache[item][p][slot] = true
  152.             end
  153.         end
  154.     end
  155.     return toMove - remaining
  156. end
  157.  
  158. --[[local function pushItem(item, count)
  159.     if item=="" or count==0 then return 0 end
  160.     local main = peripheral.wrap(mainChest)
  161.     local items = main.list()
  162.     local remaining = count
  163.     local cachefull = false
  164.     local keys = {}
  165.     local index = 0
  166.  
  167.     cache[item] = cache[item] or {}
  168.  
  169.     for slot,it in pairs(items) do
  170.         if it.name==item then
  171.             if not cachefull then
  172.                 local pushed = pushItemFromSlot(slot,item,remaining)
  173.                 remaining = remaining - pushed
  174.                 if remaining<=0 then return count end
  175.                 if pushed==0 then cachefull = true end
  176.             end
  177.             if cachefull then
  178.                 index = index + 1
  179.                 keys[index] = {slot,it.count}
  180.             end
  181.         end
  182.     end
  183.  
  184.     local function processPeriph(periphName)
  185.         cache[item][periphName] = cache[item][periphName] or {}
  186.         local chest = peripheral.wrap(periphName)
  187.         local pushed = 1
  188.         while pushed>0 and remaining>0 do
  189.             if index==0 then return count - remaining end
  190.             local slot = keys[index][1]
  191.             pushed = main.pushItems(periphName,slot,remaining)
  192.             if keys[index][2]<=pushed then
  193.                 index = index-1
  194.             else
  195.                 keys[index][2] = keys[index][2] - pushed
  196.             end
  197.             remaining = remaining - pushed
  198.         end
  199.         local items = chest.list()
  200.         for slot,it in pairs(items) do
  201.             if it.name == item then
  202.                 cache[item][periphName][slot] = true
  203.             end
  204.         end
  205.         if remaining==0 then return count end
  206.     end
  207.     for periphName in pairs(cache[item]) do
  208.         local result = processPeriph(periphName)
  209.         if result ~= nil then return result end
  210.     end
  211.     for periphName in pairs(periphs) do
  212.         if cache[item][periphName] == nil then
  213.             local result = processPeriph(periphName)
  214.             if result ~= nil then return result end
  215.         end
  216.     end
  217.     return count - remaining
  218. end]]
  219. local function returnItems()
  220.     local l = peripheral.call(mainChest,"list")
  221.     local c = {}
  222.     local a = {}
  223.     for slot,it in pairs(l) do
  224.         c[it.name] = (c[it.name] or 0) + it.count
  225.     end
  226.     for name,count in pairs(c) do
  227.         a[name] = pushItem(name,count)
  228.     end
  229.     return a
  230. end
  231. local function getCache()
  232.     return cache,periphs
  233. end
  234. local function listItems()
  235.     local keys = {}
  236.     local ln = 0
  237.     for k,v in pairs(cache) do
  238.         ln=ln+1
  239.         keys[ln]=k
  240.     end
  241.     return keys
  242. end
  243. local function countItem(item)
  244.     if cache[item]==nil then return 0 end
  245.     local c = 0
  246.     for p,slots in pairs(cache[item]) do
  247.         local items = peripheral.call(p,"list")
  248.         for i in pairs(slots) do
  249.             c=c+items[i].count
  250.         end
  251.     end
  252.     if c == 0 or next(cache[item])==nil then cache[item]=nil end
  253.     return c
  254. end
  255. local function listItemsWithCount()
  256.     local l = listItems()
  257.     local counted = {}
  258.     for i=1,#l do
  259.         counted[l[i]] = countItem(l[i])
  260.     end
  261.     return counted
  262. end
  263. local function restockMainChest()
  264.     local m = peripheral.wrap(mainChest)
  265.     for slot,item in pairs(m.list()) do
  266.         pullItem(item.name,m.getItemDetail(slot).maxCount-item.count)
  267.     end
  268. end
  269. local function sortChest(id)
  270.     local c = peripheral.wrap(id)
  271.     for slot,item in pairs(c.list()) do
  272.         c.pushItems(id,slot)
  273.     end
  274. end
  275. local function sortAllChests()
  276.     for i in pairs(periphs) do
  277.         sortChest(i)
  278.     end
  279. end
  280. return {returnItems=returnItems,pushItem=pushItem,pullItem=pullItem,
  281.     registerChests=registerChests,createCache=createCache,saveCache=saveCache,
  282.     loadCache=loadCache,getCache=getCache,setDebugMode=setDebugMode,setMainChest=setMainChest,
  283.     listItemsWithCount=listItemsWithCount,countItem=countItem,listItems=listItems,
  284.     restockMainChest=restockMainChest,sortChest=sortChest,sortAllChests=sortAllChests}
Add Comment
Please, Sign In to add comment