Advertisement
Nyhillius

rs_autocraft

Aug 25th, 2017
2,265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Refined Storage autocraft
  2. --
  3. -- Run the program with the pathname of the crafts' listing file
  4. -- Crafts file (a craft per line): [item_name] [count]
  5. -- File example: https://pastebin.com/zDrXzfSM
  6. --
  7. -- Created by Nyhillius
  8.  
  9. local event = require("event")
  10. local io = require("io")
  11. local sides = require("sides")
  12. local component = require("component")
  13. local rs = component.block_refinedstorage_interface
  14.  
  15. local args = { ... }
  16. local paths = {}
  17.  
  18. -- Print contents of `tbl`, with indentation.
  19. -- `indent` sets the initial level of indentation.
  20. function tprint (tbl, indent)
  21.   if not indent then indent = 0 end
  22.   for k, v in pairs(tbl) do
  23.     formatting = string.rep("  ", indent) .. k .. ": "
  24.     if type(v) == "table" then
  25.       print(formatting)
  26.       tprint(v, indent+1)
  27.     elseif type(v) == 'boolean' then
  28.       print(formatting .. tostring(v))      
  29.     else
  30.       print(formatting .. v)
  31.     end
  32.   end
  33. end
  34.  
  35. -- Check if the file exist
  36. local function file_exist(path)
  37.   local file = io.open(path)
  38.  
  39.   if (not file) then
  40.     print("[ERROR]: No such file: " .. path .. ".")
  41.     return false
  42.   end
  43.   io.close(file)
  44.   return true
  45. end
  46.  
  47. -- Load and parse the file, return a table with all the item to craft.
  48. local function load_file(path)
  49.   local crafts = {}
  50.  
  51.   for line in io.lines(path) do
  52.     local n, c, l, f = line:match "(%S+)%s+(%d+)"
  53.     l = n:match "(%u%S+)"
  54.     f = n:match("(%l+:%l+)")
  55.     if (l) then
  56.       table.insert(crafts, { name = f, label = l, count = c, fullName = n })
  57.     else
  58.       table.insert(crafts, { name = f, count = c, fullName = n })
  59.     end
  60.   end
  61.   return crafts
  62. end
  63.  
  64. -- Check if a task have missing items.
  65. local function is_missing_items(task)
  66.   if (task.missing.n > 0) then
  67.     return true
  68.   end
  69.   return false
  70. end
  71.  
  72. -- Check if craft is already on the tasks' queue.
  73. local function craft_is_on_tasks(craft, tasks)
  74.   for i, task in ipairs(tasks) do
  75.     if craft.name == task.stack.name then
  76.       local missing_items = rs.getMissingItems(task.stack, task.quantity)
  77.       for j, item in ipairs(missing_items) do
  78.         print("[WARNING]: Missing " .. item.size .. " " .. item.name)
  79.       end
  80.       return true
  81.     end
  82.   end
  83.   return false
  84. end
  85.  
  86. -- Craft an item
  87. function craft_item(craft, tasks)
  88.   local toCraft = tonumber(craft.count)
  89.  
  90.   if (rs.hasPattern(craft)) then
  91.     if (not craft_is_on_tasks(craft, tasks)) then
  92.       local rsStack = rs.getItem(craft)
  93.      
  94.       if (rsStack) then
  95.         toCraft = toCraft - rsStack.size
  96.       end
  97.       if (toCraft > 0) then
  98.         rs.craftItem(craft, toCraft)
  99.       end
  100.     end
  101.   else
  102.     print("[WARNING]: Missing pattern for: " .. craft.fullName .. ".")
  103.   end
  104. end
  105.  
  106. -- Destroy item
  107. function destroy_item(item)
  108.   local rs_item = rs.getItem(item)
  109.   local limit = tonumber(item.count)
  110.  
  111.   if (not rs_item) then
  112.     return
  113.   end
  114.   while (rs_item.size > limit) do
  115.     local dropped = rs.extractItem(rs_item, rs_item.size - limit, sides.down)
  116.  
  117.     rs_item.size = rs_item.size - dropped
  118.     if (dropped < 1) then
  119.       break
  120.     end
  121.   end
  122. end
  123.  
  124. -- Check the args
  125. if (#args > 0) then
  126.   paths[1] = os.getenv("PWD") .. "/" .. args[1]
  127.   if not file_exist(paths[1]) then
  128.     return
  129.   end
  130. else
  131.   print("[ERROR]: Filename is needed.")
  132.   return
  133. end
  134. if (#args > 1) then
  135.   paths[2] = os.getenv("PWD") .. "/" .. args[2]
  136.   file_exist(paths[2])
  137. end
  138.  
  139. -- The main loop ("Ctrl + C" to interrup the program)
  140. while (true) do
  141.   local crafts = load_file(paths[1])
  142.   local tasks = rs.getTasks()
  143.   local bin = nil
  144.  
  145.   -- Craft needed items
  146.   for i, craft in ipairs(crafts) do
  147.     craft_item(craft, tasks)
  148.   end
  149.  
  150.   -- Destroy items
  151.   if (paths[2]) then
  152.     bin = load_file(paths[2])
  153.     for i, item in ipairs(bin) do
  154.       destroy_item(item)
  155.     end
  156.   end
  157.  
  158.   -- Event handler
  159.   local id = event.pull(5, "interrupted")
  160.   if (id == "interrupted") then
  161.     print("Program stopped.")
  162.     break
  163.   end
  164. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement