Advertisement
Lordeah18

stocker.lua

Nov 23rd, 2024
185
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.19 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(config)
  52.     local missingItems = {}
  53.  
  54.     for _, ingredient in ipairs(config.ingredients) do
  55.         local itemName = ingredient.name
  56.         local requiredQuantity = ingredient.quantity or 1
  57.         local availableQuantity = 0
  58.  
  59.         -- Determine the source for this specific ingredient
  60.         local sourcePeripheral = peripheral.wrap(ingredient.source or config.source or defaultSourcePeripheral)
  61.         if not sourcePeripheral then
  62.             print("Error: Could not find source peripheral for " .. itemName)
  63.             table.insert(missingItems, { name = itemName, missing = requiredQuantity })
  64.         else
  65.             -- Accumulate the count of the item in the source inventory
  66.             for slot, itemDetail in pairs(sourcePeripheral.list()) do
  67.                 if itemDetail.name == itemName then
  68.                     availableQuantity = availableQuantity + itemDetail.count
  69.                 end
  70.             end
  71.  
  72.             -- Add to missing items if quantity is insufficient
  73.             if availableQuantity < requiredQuantity then
  74.                 table.insert(missingItems, {
  75.                     name = itemName,
  76.                     missing = requiredQuantity - availableQuantity
  77.                 })
  78.             end
  79.         end
  80.     end
  81.  
  82.     -- Return list of missing items and a flag indicating if all are available
  83.     return missingItems, #missingItems == 0
  84. end
  85.  
  86. -- Transfers ingredients to the processing input peripheral
  87. local function transferIngredients(ingredients, processingInput)
  88.     local inputPeripheral = peripheral.wrap(processingInput)
  89.     if not inputPeripheral then
  90.         print("Error: Could not find processing input peripheral.")
  91.         return false
  92.     end
  93.  
  94.     for _, ingredient in ipairs(ingredients) do
  95.         local ingredientName = ingredient.name
  96.         local quantity = ingredient.quantity or 1
  97.         local sourcePeripheral = peripheral.wrap(ingredient.source)
  98.  
  99.         if not sourcePeripheral then
  100.             print("Error: Could not find source peripheral for " .. ingredientName)
  101.             return false
  102.         end
  103.  
  104.         local transferred = 0
  105.         for slot, item in pairs(sourcePeripheral.list()) do
  106.             if item.name == ingredientName then
  107.                 local toTransfer = math.min(quantity - transferred, item.count)
  108.                 inputPeripheral.pullItems(peripheral.getName(sourcePeripheral), slot, toTransfer)
  109.                 transferred = transferred + toTransfer
  110.                 if transferred >= quantity then break end
  111.             end
  112.         end
  113.  
  114.         if transferred < quantity then
  115.             print("Error: Not enough " .. ingredientName .. " available.")
  116.             return false
  117.         end
  118.     end
  119.     return true
  120. end
  121.  
  122. local function waitForProduct(processingInput)
  123.     local inputPeripheral = peripheral.wrap(processingInput)
  124.     while #inputPeripheral.list() > 0 do
  125.         os.sleep(1)
  126.     end
  127. end
  128.  
  129. -- Transfers finished products to the stock destination peripheral
  130. local function transferProduct(productName, processingOutput, destination)
  131.     local outputPeripheral = peripheral.wrap(processingOutput)
  132.     local destinationPeripheral = peripheral.wrap(destination)
  133.  
  134.     if not outputPeripheral or not destinationPeripheral then
  135.         print("Error: Could not find processing output or destination peripheral.")
  136.         return
  137.     end
  138.  
  139.     for slot, item in pairs(outputPeripheral.list()) do
  140.         if item.name == productName then
  141.             outputPeripheral.pushItems(peripheral.getName(destinationPeripheral), slot)
  142.         end
  143.     end
  144. end
  145.  
  146. -- Displays status on the monitor
  147. local function displayStatus(config, currentStock, ingredientsReady)
  148.     local monitor = peripheral.wrap(monitorPeripheral)
  149.     if not monitor then
  150.         print("Error: Monitor not found.")
  151.         return
  152.     end
  153.  
  154.     monitor.clear()
  155.     monitor.setCursorPos(1, 1)
  156.     monitor.write("Stock Management:")
  157.     monitor.setCursorPos(1, 2)
  158.     monitor.write("- Product: " .. config.product)
  159.     monitor.setCursorPos(1, 3)
  160.     monitor.write("- Required Stock: " .. config.stock)
  161.     monitor.setCursorPos(1, 4)
  162.     monitor.write("- Current Stock: " .. currentStock)
  163.     monitor.setCursorPos(1, 5)
  164.     monitor.write("- Ingredients Ready: " .. (ingredientsReady and "Yes" or "No"))
  165. end
  166.  
  167. -- Main logic
  168. local function main()
  169.     local configFiles = readConfigFiles(configFolder)
  170.     for _, config in ipairs(configFiles) do
  171.         local productName = config.product
  172.         local requiredStock = config.stock
  173.         local destination = config.destination
  174.         local processingInput = config.processing_input
  175.         -- If output doesn't exist, assume it's the same block as the input
  176.         local processingOutput = config.processing_output or config.processing_input
  177.         local ingredients = config.ingredients
  178.         local batchSize = config.batch_size or 1
  179.         -- Check current stock level
  180.         local currentStock = checkStockLevel(productName, destination)
  181.         local ingredientsReady = false
  182.  
  183.         if currentStock < requiredStock then
  184.             local amountNeeded = math.ceil((requiredStock - currentStock) / batchSize)
  185.             print("Low stock for " .. productName .. ": Need " .. amountNeeded .. " batches")
  186.            
  187.             -- Adjust ingredient quantities based on amount needed
  188.             for _, ingredient in ipairs(ingredients) do
  189.                 -- If source is missing, assume the source is the same as the destination
  190.                 ingredient.source = ingredient.source or config.destination
  191.                 ingredient.quantity = ingredient.quantity * amountNeeded
  192.             end
  193.  
  194.             local missingItems, allAvailable = checkMissingItems(config)
  195.  
  196.             if allAvailable then
  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.                
  206.                 waitForProduct(processingInput)
  207.  
  208.                 -- Transfer finished product to stock destination
  209.                 transferProduct(productName, processingOutput, destination)
  210.        
  211.                 -- Display status on the monitor
  212.                 displayStatus(config, currentStock, ingredientsReady)
  213.        
  214.             else
  215.                 displayMissingResources(missingItems)
  216.             end
  217.         end
  218.     end
  219.     print("Stock management cycle complete.")
  220. end
  221.  
  222.  
  223. while true do
  224.     main()
  225.     os.sleep(10)
  226. end
  227.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement