Altaric

Minecraft

Dec 24th, 2021 (edited)
746
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.87 KB | None | 0 0
  1. print("Autocraft v1")
  2.  
  3. -- Configuration
  4.  
  5. maxTasks=2     -- overridden in rules.cfg
  6. maxTaskSize=20 -- overridden in rules.cfg
  7. screenSize=40  -- overridden in rules.cfg
  8. function buildRules()
  9.     -- readConfig()
  10.     rules = {}
  11.     table.insert(rules, {count=20,  name="opencomputers:material", dmg=4, label="Circuit Board", limit=100})
  12.     table.insert(rules, {count=200, name="opencomputers:material", dmg=4, label="PCB", limit=100})
  13.     table.insert(rules, {count=200, name="opencomputers:material", dmg=7, label="Chip1", limit=100})
  14.     table.insert(rules, {count=20,  name="opencomputers:material", dmg=8, label="Chip2", limit=20})
  15.     table.insert(rules, {count=10,  name="opencomputers:material", dmg=9, label="Chip3", limit=10})
  16.     table.insert(rules, {count=1024, name="projectred-core:ressource_item", dmg=0, label="Circuit Plate", limit=300})
  17.     table.insert(rules, {count=500, name="mekanism:controlcircuit", dmg=0, label="Basic Control Circuit", limit=200})
  18.     table.insert(rules, {count=100, name="mekanism:controlcircuit", dmg=1, label="Adv Control Circuit", limit=50})
  19.     table.insert(rules, {count=20,  name="mekanism:controlcircuit", dmg=2, label="Elite Control Circuit", limit=10})
  20.     table.insert(rules, {count=2,   name="mekanism:controlcircuit", dmg=3, label="Ultim Control Circuit", limit=2})
  21.     -- table.insert(rules, {count=10, name="thermalfoundation:material", dmg=324})
  22.     addRulesWiggle("Plate", 10, 10)
  23.     addRulesWiggle("Ingot", 20, 20)
  24.     saveConfig()
  25. end
  26.  
  27.  
  28. -- Imports
  29.  
  30. local component = require("component")
  31. local sides = require("sides")
  32. local term = require("term")
  33. local event = require("event")
  34. local meController = component.me_controller
  35. local invController = component.inventory_controller
  36. local RSController = component.redstone
  37.  
  38. -- Utilities
  39.  
  40. function mysplit (inputstr, sep)
  41.         if sep == nil then
  42.                 sep = "%s"
  43.         end
  44.         local t={}
  45.         for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
  46.                 table.insert(t, str)
  47.         end
  48.         return t
  49. end
  50.  
  51. -- Actual code
  52.  
  53. term.clear()
  54. tasks = {}
  55.  
  56. function readChest()
  57.     print("Reading chest...")
  58.     b = false
  59.     for side= 0, 5 do
  60.         n = invController.getInventorySize(side)
  61.         print(sides[side].." : "..(n or "nil"))
  62.         if n then
  63.             for i = 1, n do
  64.                 it=invController.getStackInSlot(side, i)
  65.                 if it then print(it.name.."/"..it.damage) b = true end
  66.             end
  67.         end
  68.     end
  69.     if b then os.sleep(2) end
  70. end
  71.  
  72. function checkAvailableCPUs()
  73.     meCpus = meController.getCpus()
  74.     local occupiedCpus = 0
  75.     acpus = 0
  76.     for cpuIndex = 1, #meCpus do
  77.         -- if not meCpus[cpuIndex].busy then table.insert(acpus, meCpus[cpuIndex]) end
  78.         if not meCpus[cpuIndex].busy then acpus = acpus+1 end
  79.     end
  80.     return acpus
  81. end
  82.  
  83. function checkIfTasksEnded()
  84.     for i, t in pairs(tasks) do
  85.         tt = t.task
  86.         if tt.isDone() then
  87.             table.remove(tasks, i)
  88.             print("Task finished: "..t.label)
  89.         elseif tt.isCanceled() then
  90.             table.remove(tasks, i)
  91.             print("!! Task canceled: "..t.label.." !!")
  92.         else
  93.             print("Task running: "..t.label)           
  94.         end
  95.     end
  96. end
  97.  
  98. function printStock(verbose)
  99.     l = 0
  100.     for _, rule in pairs(rules) do
  101.         if rule["dmg"] then
  102.             meItems = meController.getItemsInNetwork({ name = rule["name"], damage = rule["dmg"]})
  103.         else
  104.             meItems = meController.getItemsInNetwork({ name = rule["name"]})
  105.         end
  106.         if meItems.n == 0 then
  107.             print("Could not find "..rule["name"].."/"..(rule["dmg"] or "*"))
  108.             l = l + 1
  109.             if l > screenSize then os.sleep(2) l = 0 end
  110.             goto nextRule          
  111.         end
  112.  
  113.         if meItems.n == 1 then
  114.             if (verbose == "all") then print(rule["name"].."/"..(rule["dmg"] or "*").. " -> "..meItems[1].label.. " " .. meItems[1].size.."/"..rule["count"]) l = l + 1 if l > screenSize then os.sleep(2) l = 0 end end
  115.             if (verbose == "missing") and (meItems[1].size < rule["count"]) then print(rule["name"].."/"..(rule["dmg"] or "*").. " -> "..meItems[1].label.. " " .. meItems[1].size.."/"..rule["count"]) l = l + 1 if l > screenSize then os.sleep(2) l = 0 end end
  116.            
  117.         else
  118.             if (verbose == "all") then print(rule["name"].."/"..(rule["dmg"] or "*")) end
  119.             for i=1, meItems.n do
  120.                 it = meItems[i]
  121.                 if (verbose == "all") then print(it.label .. " " .. it.size.."/"..rule["count"]) l = l + 1 if l > screenSize then os.sleep(2) l = 0 end end
  122.                 if (verbose == "missing") and (it.size < rule["count"]) then print(it.label .. " " .. it.size.."/"..rule["count"]) l = l + 1 if l > screenSize then os.sleep(2) l = 0 end end
  123.             end
  124.         end
  125.         ::nextRule::
  126.     end
  127. end
  128.  
  129. function checkItemsAndCraft(cpus)
  130.     l = 0
  131.     for _, rule in pairs(rules) do
  132.         if rule["dmg"] then
  133.             meItems = meController.getItemsInNetwork({ name = rule["name"], damage = rule["dmg"]})
  134.         else
  135.             meItems = meController.getItemsInNetwork({ name = rule["name"]})
  136.         end
  137.         if meItems.n == 0 then
  138.             print("Could not find "..rule["name"].."/"..(rule["dmg"] or "*"))
  139.             l = l + 1
  140.             if l > screenSize then os.sleep(2) l = 0 end
  141.         else
  142.             for i=1, meItems.n do
  143.                 it = meItems[i]
  144.                 result = orderMissingItem(cpus, it, rule["count"], rule["limit"])
  145.                 if (result == 3) or (result == 4) then return end -- no need to continue.
  146.             end
  147.         end
  148.     end
  149. end
  150.  
  151. -- return values:
  152. -- -1 Nothing to do
  153. -- 0 success
  154. -- 1 already running
  155. -- 2 missing ingredients
  156. -- 3 max tasks reached
  157. -- 4 max CPUs reached
  158. -- 5 No recipe
  159.  
  160. function orderMissingItem(cpus, item, target, limit)
  161.  
  162.     -- checks --
  163.     for _, t in pairs(tasks) do
  164.         if (t.name == item.name) and (t.dmg == item.damage) then
  165.             print("Already crafting ".. item.label)
  166.             return 1
  167.         end
  168.     end
  169.     if #tasks >= maxTasks then      print("Max concurent tasks reached.")       return 3    end
  170.     if cpus <= 1 then       print("No CPU available.")      return 4    end
  171.     if item.size >= target then         return -1   end
  172.    
  173.     -- Order the craft
  174.     needed = math.min(limit, target - item.size)
  175.     craftables = meController.getCraftables({ name = item.name, damage = item.damage})
  176.     if craftables.n == 0 then       print("No recipe for ".. item.label)        return 5    end
  177.     for i=1, craftables.n do
  178.         craftable = craftables[i]
  179.         task = craftable.request(needed)
  180.         if task.isCanceled() then
  181.             print("Missing ingredients for "..item.label.." recipe "..i)
  182.         else
  183.             print("Ordered "..needed.." "..item.label.." (recipe "..i..")")
  184.             table.insert(tasks, {name=item.name, dmg=item.damage, task=task, label=item.label})
  185.             cpus = cpus - 1
  186.             return 0
  187.         end
  188.     end
  189. end
  190.  
  191. function readConfig()
  192.     local file,err = io.open("rules.cfg", "r")
  193.     if err == nil then
  194.         version = tonumber(file:read("*line"))
  195.         if version == 1 then
  196.             maxTasks = tonumber(file:read("*line"))
  197.             maxTaskSize = tonumber(file:read("*line"))
  198.             screenSize = tonumber(file:read("*line"))
  199.            
  200.             l = file:read("*line")
  201.             -- rules={}
  202.             while l ~= 1 do
  203.                 s = mysplit(l, "\t")
  204.                 -- print(tonumber(s[1]).."  "..s[2].."/"..tonumber(s[3]))
  205.                 table.insert(rules, {count=tonumber(s[1]), name=s[2], dmg=tonumber(s[3]), limit=maxTaskSize})
  206.                 l = file:read("*line")
  207.             end
  208.         end
  209.         if version == 2 then
  210.             maxTasks = tonumber(file:read("*line"))
  211.             maxTaskSize = tonumber(file:read("*line"))
  212.             screenSize = tonumber(file:read("*line"))
  213.            
  214.             l = file:read("*line")
  215.             -- rules={}
  216.             while l ~= 1 do
  217.                 s = mysplit(l, "\t")
  218.                 -- print(tonumber(s[1]).."  "..s[2].."/"..tonumber(s[3]))
  219.                 table.insert(rules, {count=tonumber(s[1]), name=s[2], dmg=tonumber(s[3]), limit=tonumber(s[4])})
  220.                 l = file:read("*line")
  221.             end
  222.         end
  223.         file:close()
  224.     end
  225. end
  226.  
  227. function saveConfig()
  228.     local file,err = io.open("rules.cfg", "w")
  229.     file:write("2\n")
  230.     file:write(maxTasks.."\n")
  231.     file:write(maxTaskSize.."\n")
  232.     file:write(screenSize.."\n")
  233.     for _, i in pairs(rules) do
  234.         file:write(i.count.."\t"..i.name.."\t"..i.dmg.."\t"..(i.label or "-").."\t"..(i.limit or "-").."\n")
  235.     end
  236.     file:close()
  237. end
  238.  
  239. function addRulesWiggle(name, qty, limit)
  240.     print("Adding wiggle rule ; this is quite long!")
  241.     craftables = meController.getCraftables()
  242.     print(craftables.n)
  243.     for i=1, craftables.n do
  244.         if ((i % 100) == 0) then print(i) end
  245.         if string.find(craftables[i].getItemStack().label, name) then
  246.             print(craftables[i].getItemStack().label)
  247.             table.insert(rules, {count=qty, name=craftables[i].getItemStack().name, dmg=craftables[i].getItemStack().damage, label=craftables[i].getItemStack().label, limit=limit})
  248.         end
  249.     end
  250.  
  251. end
  252.  
  253. -- Main loop
  254. -- readChest()
  255. buildRules()
  256. iter=1
  257. -- craftables = meController.getCraftables()
  258. -- print(craftables.n)
  259. -- for i=1, craftables.n do
  260.     -- if string.find(craftables[i].getItemStack().label, "Ingot") then print(craftables[i].getItemStack().label) end
  261. -- end
  262. while (RSController.getInput(sides.left) == 0) do
  263.     -- term.clear()
  264.     print("Iteration "..iter.. ". Flip the switch to the right to exit.\n")
  265.     cpus = checkAvailableCPUs()
  266.     checkIfTasksEnded()
  267.     print(cpus.." CPUs available. "..#tasks.." Tasks running.\n")
  268.     printStock("missing")
  269.     if ((cpus > 1) and (#tasks < maxTasks))then
  270.         checkItemsAndCraft(cpus)
  271.     end
  272.     os.sleep(5)
  273.     iter = iter +1
  274. end
Add Comment
Please, Sign In to add comment