Advertisement
Lordeah18

stocker.lua

Nov 23rd, 2024
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.80 KB | None | 0 0
  1. if not fs.exists("json") then
  2.     shell.run("pastebin get 4nRg9CHU json")
  3. end
  4.  
  5. os.loadAPI("json")
  6.  
  7. local configFolder = "stock_config"
  8. local monitorPeripheral = "top"
  9.  
  10. -- Reads configuration files
  11. local function readConfigFiles(folder)
  12.     local configs = {}
  13.     if fs.exists(folder) and fs.isDir(folder) then
  14.         for _, file in ipairs(fs.list(folder)) do
  15.             local filePath = fs.combine(folder, file)
  16.             if fs.isDir(filePath) == false then
  17.                 local fileHandle = fs.open(filePath, "r")
  18.                 if fileHandle then
  19.                     local content = fileHandle.readAll()
  20.                     fileHandle.close()
  21.                     local parsed = json.decode(content)
  22.                     if parsed then
  23.                         table.insert(configs, parsed)
  24.                     end
  25.                 end
  26.             end
  27.         end
  28.     end
  29.     return configs
  30. end
  31.  
  32. -- Checks the stock level of a product
  33. local function checkStockLevel(itemName, destinationPeripheral)
  34.     local stockPeripheral = peripheral.wrap(destinationPeripheral)
  35.     if not stockPeripheral then
  36.         print("Error: Could not find destination peripheral.")
  37.         return 0
  38.     end
  39.  
  40.     local currentStock = 0
  41.     for _, item in pairs(stockPeripheral.list()) do
  42.         if item.name == itemName then
  43.             currentStock = currentStock + item.count
  44.         end
  45.     end
  46.     return currentStock
  47. end
  48.  
  49.  
  50. -- Checks for missing items in the source inventory
  51. local function checkMissingItems(itemConfig)
  52.     local missingItems = {}
  53.     local source = peripheral.wrap(itemConfig.source or defaultSourcePeripheral)
  54.     if not source then
  55.         print("Error: Could not find source peripheral.")
  56.         return missingItems, false
  57.     end
  58.  
  59.     for _, item in ipairs(itemConfig.items) do
  60.         local itemName = item.name
  61.         local requiredQuantity = item.quantity or 1
  62.         local availableQuantity = 0
  63.  
  64.         -- Check inventory for item and accumulate total countכא'
  65.         for slot, itemDetail in pairs(source.list()) do
  66.             if itemDetail.name == itemName then
  67.                 availableQuantity = availableQuantity + itemDetail.count
  68.             end
  69.         end
  70.  
  71.         -- Add to missing items if insufficient quantity
  72.         if availableQuantity < requiredQuantity then
  73.             table.insert(missingItems, {
  74.                 name = itemName,
  75.                 missing = requiredQuantity - availableQuantity
  76.             })
  77.         end
  78.     end
  79.  
  80.     return missingItems, #missingItems == 0
  81. end
  82.  
  83. -- Transfers ingredients to the processing input peripheral
  84. local function transferIngredients(ingredients, processingInput)
  85.     local inputPeripheral = peripheral.wrap(processingInput)
  86.     if not inputPeripheral then
  87.         print("Error: Could not find processing input peripheral.")
  88.         return false
  89.     end
  90.  
  91.     for _, ingredient in ipairs(ingredients) do
  92.         local ingredientName = ingredient.name
  93.         local quantity = ingredient.quantity or 1
  94.         local sourcePeripheral = peripheral.wrap(ingredient.source)
  95.  
  96.         if not sourcePeripheral then
  97.             print("Error: Could not find source peripheral for " .. ingredientName)
  98.             return false
  99.         end
  100.  
  101.         local transferred = 0
  102.         for slot, item in pairs(sourcePeripheral.list()) do
  103.             if item.name == ingredientName then
  104.                 local toTransfer = math.min(quantity - transferred, item.count)
  105.                 inputPeripheral.pullItems(peripheral.getName(sourcePeripheral), slot, toTransfer)
  106.                 transferred = transferred + toTransfer
  107.                 if transferred >= quantity then break end
  108.             end
  109.         end
  110.  
  111.         if transferred < quantity then
  112.             print("Error: Not enough " .. ingredientName .. " available.")
  113.             return false
  114.         end
  115.     end
  116.     return true
  117. end
  118.  
  119. local function waitForProduct(processingInput)
  120.     local inputPeripheral = peripheral.wrap(processingInput)
  121.     while #inputPeripheral.list() > 0 do
  122.         os.sleep(1)
  123.     end
  124. end
  125.  
  126. -- Transfers finished products to the stock destination peripheral
  127. local function transferProduct(productName, processingOutput, destination)
  128.     local outputPeripheral = peripheral.wrap(processingOutput)
  129.     local destinationPeripheral = peripheral.wrap(destination)
  130.  
  131.     if not outputPeripheral or not destinationPeripheral then
  132.         print("Error: Could not find processing output or destination peripheral.")
  133.         return
  134.     end
  135.  
  136.     for slot, item in pairs(outputPeripheral.list()) do
  137.         if item.name == productName then
  138.             outputPeripheral.pushItems(peripheral.getName(destinationPeripheral), slot)
  139.         end
  140.     end
  141. end
  142.  
  143. -- Displays status on the monitor
  144. local function displayStatus(config, currentStock, ingredientsReady)
  145.     local monitor = peripheral.wrap(monitorPeripheral)
  146.     if not monitor then
  147.         print("Error: Monitor not found.")
  148.         return
  149.     end
  150.  
  151.     monitor.clear()
  152.     monitor.setCursorPos(1, 1)
  153.     monitor.write("Stock Management:")
  154.     monitor.setCursorPos(1, 2)
  155.     monitor.write("- Product: " .. config.product)
  156.     monitor.setCursorPos(1, 3)
  157.     monitor.write("- Required Stock: " .. config.stock)
  158.     monitor.setCursorPos(1, 4)
  159.     monitor.write("- Current Stock: " .. currentStock)
  160.     monitor.setCursorPos(1, 5)
  161.     monitor.write("- Ingredients Ready: " .. (ingredientsReady and "Yes" or "No"))
  162. end
  163.  
  164. -- Main logic
  165. local function main()
  166.     local configFiles = readConfigFiles(configFolder)
  167.     for _, config in ipairs(configFiles) do
  168.         local productName = config.product
  169.         local requiredStock = config.stock
  170.         local destination = config.destination
  171.         local processingInput = config.processing_input
  172.         -- If output doesn't exist, assume it's the same block as the input
  173.         local processingOutput = config.processing_output or config.processing_input
  174.         local ingredients = config.ingredients
  175.         local batchSize = config.batch_size or 1
  176.         -- Check current stock level
  177.         local currentStock = checkStockLevel(productName, destination)
  178.         local ingredientsReady = false
  179.  
  180.         if currentStock < requiredStock then
  181.             local amountNeeded = math.ceil((requiredStock - currentStock) / batchSize)
  182.             print("Low stock for " .. productName .. ": Need " .. amountNeeded .. " batches")
  183.            
  184.             -- Adjust ingredient quantities based on amount needed
  185.             for _, ingredient in ipairs(ingredients) do
  186.                 -- If source is missing, assume the source is the same as the destination
  187.                 ingredient.source = ingredient.source or config.destination
  188.                 ingredient.quantity = ingredient.quantity * amountNeeded
  189.             end
  190.  
  191.             local missingItems, allAvailable = checkMissingItems(config)
  192.  
  193.             if not allAvailable then
  194.                 displayMissingResources(missingItems)
  195.                 goto continue
  196.             end
  197.             -- Transfer ingredients to processing input
  198.             ingredientsReady = transferIngredients(ingredients, processingInput)
  199.  
  200.             if ingredientsReady then
  201.                 print("Ingredients for " .. productName .. " placed in processing input.")
  202.             else
  203.                 print("Could not transfer ingredients for " .. productName .. ".")
  204.             end
  205.         end
  206.        
  207.         waitForProduct(processingInput)
  208.  
  209.         -- Transfer finished product to stock destination
  210.         transferProduct(productName, processingOutput, destination)
  211.  
  212.         -- Display status on the monitor
  213.         displayStatus(config, currentStock, ingredientsReady)
  214.        
  215.         ::continue::
  216.  
  217.     end
  218.     print("Stock management cycle complete.")
  219. end
  220.  
  221.  
  222. while true do
  223.     main()
  224.     os.sleep(10)
  225. end
  226.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement