Advertisement
CreeperNukeBoom

NAFA (Not Another Furnace Automater)

Jan 17th, 2020
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.32 KB | None | 0 0
  1. --[[
  2. NAFA - Not another Furnace Automater by CreeperGoBoom
  3. This program works in 2 simple steps.
  4. 1. Network your chests and furnaces up.
  5. 2. Install this program onto a networked computer.
  6.  
  7. Alternatively you could set this up first and it will detect all new chests and furnaces as you set up.
  8.  
  9. To reconfigure chest / furnace layout:
  10. Simply add and remove furnaces ((Coming soon!) and chests) as required.
  11.  
  12. BUGFIXES:
  13. -Fixed furnaces crashing script due to disconnect bug.
  14. -Note: Now each furnace that disconnects is removed and then readded to furnace list.
  15.  
  16. TODO:
  17. -Chest readding and checking like furnaces.
  18. -Table to keep track of peripheral types.
  19. -Shulker boxes.
  20.  
  21. FEATURES:
  22. -Now runs in parallel, additional event features now possible.
  23. -Now feeds fuel and ingredients based on vars below.
  24. -For example, if a furnace runs out of fuel. it will then send fuel at the fuel rate specified
  25.  and wait for the furnace to run out before refueling.
  26. -Plethora optimized.
  27. -Fuel and ingredient rates shown on main screen.
  28. ]]
  29.  
  30. --VARS
  31. local furnaceFuelRate = 1  --How much fuel will be placed into the furnaces when empty?
  32. local furnaceIngredientsRate = 8  --How many ingredients to send to furnaces at one time?
  33. local ingredients = {"minecraft:cobblestone", "minecraft:sand", "minecraft:iron_ore", "minecraft:gold_ore", "minecraft:log" }
  34. local fuels = {"minecraft:coal", "minecraft:sapling"}
  35. local idprint = false   --saves all item data from chests into file idprint.lua
  36.  
  37. local requiredAPIFuncs = {
  38.   "fileWrite",
  39.   "saveConfig",
  40.   "colorPrint",
  41.   "getPeripherals",
  42.   }
  43.  
  44. local function httpGet(stringURL, stringFileNameToSaveTo)
  45.   local h, err = http.get(stringURL)
  46.   if not h then printError(err) return nil end
  47.   local f = fs.open(stringFileNameToSaveTo, "w")
  48.   f.write(h.readAll())
  49.   f.close()
  50.   h.close()
  51.   return true
  52. end
  53.  
  54. if not fs.exists("apis/CGBCoreLib.lua") then
  55.   if not httpGet("https://pastebin.com/raw/xuMVS2GP", "apis/CGBCoreLib.lua") then
  56.     error("Error: Dependancy 'CGBCoreLib' could not be downloaded. Please connect your internet and restart")
  57. end
  58.  
  59. local core = require("apis/CGBCoreLib") --Contains complete function library used accross multiple programs and to minimize code size.
  60.  
  61. for _ , func in pairs(requiredAPIFuncs) do --For API checking to ensure not outdated
  62.   if not core[func] then
  63.     if not httpGet("https://pastebin.com/raw/xuMVS2GP", "apis/CGBCoreLib.lua") then
  64.       error("Error: Your version of CGBCoreLib is outdated! Please connect your internet and restart!")
  65.     else
  66.       os.reboot()
  67.     end
  68.   end
  69. end
  70.  
  71. local furnaces
  72. local chests
  73. local shulkers
  74. local storage
  75. local data = {}
  76. local debug = {}
  77.  
  78. local function getItemList(chestName)
  79.   local meta = peripheral.call(chestName,"list")
  80.   return meta
  81. end
  82.  
  83. local function getChestInfo()
  84.   local meta = {}
  85.   for key, val in pairs(storage) do
  86.     meta.chestName = val.name
  87.     meta[val] = getItemList(val)
  88.   end
  89.   if idprint then
  90.     local sData = textutils.serialize(meta)
  91.     core.fileWrite("data/idprint.lua", sData)
  92.   end
  93.   core.saveConfig("data.lua",meta)
  94.   return meta
  95. end
  96.  
  97. local function getStorage(...)
  98.   local temp = {}
  99.   local temp2 = {}
  100.   local count = 1
  101.   local peripherals = peripheral.getNames()
  102.   for k , v in pairs({...}) do
  103.     for _ , name in pairs(peripherals) do
  104.       if name:find(v) then
  105.         table.insert(temp,name)
  106.       end
  107.     end
  108.   end
  109.   return temp
  110. end
  111.    
  112.  
  113. local function main()
  114.   term.clear()
  115.   term.setCursorPos(1, 1)
  116.   core.colorPrint("orange","NAFA V1.2 (Not Another Furnace Automater)")
  117.   furnaces = core.getPeripherals("furnace")
  118.   storage = getStorage("chest","shulker")
  119.   core.saveConfig("storage.lua",storage)
  120.   data = getChestInfo()
  121.  
  122.   --Statuses
  123.   if not storage[1] then
  124.     core.colorPrint("red","STATUS: No Storage found!")
  125.     sleep(5)
  126.   elseif not furnaces[1] then
  127.     core.colorPrint("red","STATUS: No Furnaces found!")
  128.     sleep(5)
  129.   elseif storage[1] and furnaces[1] then
  130.     core.colorPrint("green","STATUS: OK!")
  131.     core.colorPrint("green","Fuel rate: " .. furnaceFuelRate .. " per refuel.")
  132.     core.colorPrint("green","Ingredient rate: " .. furnaceIngredientsRate .. " per refill.")
  133.   end
  134.  
  135.   --Main operation code
  136.   if furnaces[1] and storage[1] then
  137.     --for chestNum , chest in pairs(storage) do
  138.       for furnaceNum , furnace in ipairs(furnaces) do
  139.         for chestName , chestContents in pairs(data) do
  140.           local success  = pcall(function ()
  141.             furnaceContents = peripheral.call(furnace, "list")
  142.             for slot , item in pairs(chestContents) do
  143.               --[[Basic order of operation here:
  144.                   1.Check if theres any output to push to chests.
  145.                   No point checking fuel levels or ingredients if furnace output is full.
  146.                   This allows other furnaces to be used in this case.
  147.                  
  148.                   2.Check fuel.
  149.                   Refuel if needed.
  150.                  
  151.                   3.Check that ingredients slot is empty.
  152.                   Send new lot of ingredients as per vars at top.]]
  153.               if furnaceContents[3] and furnaceContents[3].count then --only pushes items out if theres something there else it wont call it, makes it more plethora friendly.
  154.                 peripheral.call(furnace, "pushItems", chestName, 3, furnaceContents[3].count)
  155.               elseif not (furnaceContents[2] and furnaceContents[2].count) then -- Refuel
  156.                 for _ , fuel in ipairs(fuels) do
  157.                   if item.name == fuel then
  158.                     table.insert(debug,furnace .. " received " .. furnaceFuelRate .. " fuel from " .. chestName)
  159.                     if pcall(peripheral.call,chestName, "pushItems", furnace, slot, furnaceFuelRate, 2) then
  160.                       break
  161.                     end
  162.                   end
  163.                 end
  164.               elseif not (furnaceContents[1] and furnaceContents[1].count) then -- Refill ingredients
  165.                 for _ , ingredient in ipairs(ingredients) do
  166.                   if item.name == ingredient then
  167.                     table.insert(debug,furnace .. " received " .. furnaceIngredientsRate .. " " .. item.name .. " from " .. chestName)
  168.                     if pcall(peripheral.call,chestName, "pushItems", furnace, slot, furnaceIngredientsRate, 1) then
  169.                       break
  170.                     end
  171.                   end
  172.                 end
  173.               end
  174.             end
  175.           end)
  176.           if not success then
  177.             table.remove(furnaces, furnaceNum)
  178.           end
  179.         end
  180.       end
  181.     --end
  182.   end
  183.   core.saveConfig("debug.lua",debug)
  184. end
  185.  
  186. local function secondary()
  187.   local x = 10 -- interval in seconds
  188.   local tmr = os.startTimer(x)
  189.   while true do
  190.     local event = {os.pullEvent()}
  191.     if event[1] == "timer" and event[2] == tmr then
  192.       os.queueEvent("runmain") -- tell maim func to run
  193.       tmr = os.startTimer(x)
  194.     elseif event[1] == "peripheral_detach" then
  195.       for k , v in pairs(furnaces) do
  196.         if v == event[2] then
  197.           table.remove(furnaces, k)
  198.           break
  199.         end
  200.       end
  201.     elseif event[1] == "peripheral" then
  202.       if peripheral.getType(event[2]) == "furnace" then
  203.         table.insert(furnaces, #furnaces + 1, event[2])
  204.       end
  205.     end
  206.   end
  207. end
  208.  
  209.  
  210. while true do
  211.   parallel.waitForAny(main, secondary)
  212. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement