Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- print("Autocraft v1.1")
- -- Configuration
- maxTasks=2 -- overridden in rules.cfg
- maxTaskSize=20 -- overridden in rules.cfg
- screenSize=40 -- overridden in rules.cfg
- function buildRules()
- rules = {}
- readConfig()
- -- addRule(20 , "minecraft:brick" , "*" , "Brick Vanilla", 20)
- -- addRule(20 , "nuclearcraft:alloy" , 1 , "Tough Alloy", 20)
- -- addRule(20 , "nuclearcraft:alloy" , 2 , "Hard Carbon Alloy", 20)
- -- addRule(20 , "nuclearcraft:alloy" , 6 , "Ferroboron Alloy", 20)
- -- addRule(20 , "nuclearcraft:alloy" , 9 , "Lead-Plat Ingot", 20)
- -- addRule(20 , "nuclearcraft:alloy" , 10 , "Extreme Alloy", 20)
- -- addRule(20 , "projectred-core:resource_item", 103 , "Red Alloy Ingot", 20)
- -- addRule(20 , "projectred-core:resource_item", 104 , "Electrotine Ingot", 20)
- -- addRule(20 , "bloodarsenal:base_item", 4 , "Blood Iron Ingot", 20)
- -- addRule(20 , "thermaldynamics:servo" , 4 , "Resonant Servo", 20)
- -- addRule(20 , "thermaldynamics:filter" , 4 , "Resonant Filter", 20)
- -- addRule(100 , "thermaldynamics:duct_32" , 7 , "Plated Impulse Duct Opaque", 100)
- -- addRule(64 , "immersiveengineering:stone_decoration" , 5 , "Concrete immersive", 10)
- -- addRule(500 , "mysticalagriculture:crafting" , 1 , "Prudentium Essence", 100)
- -- addRule(100 , "mysticalagriculture:crafting" , 2 , "Intermedium Essence", 20)
- -- addRule(20 , "mysticalagriculture:crafting" , 3 , "Superium Essence", 5)
- -- addRule(5 , "mysticalagriculture:crafting" , 4 , "Supremium Essence", 2)
- -- addRule(20 , "appliedenergistics2:material" , 22 , "Logic Processor", 5)
- -- addRule(5 , "appliedenergistics2:material" , 23 , "Calculation Processor", 5)
- -- addRule(5 , "appliedenergistics2:material" , 24 , "Engineering Processor", 5)
- -- addRule(1024, "minecraft:glass" , "*", "Glass", 128)
- -- addRule(20 , "opencomputers:material" , 3 , "Circuit Board", 100)
- -- addRule(200 , "opencomputers:material" , 4 , "PCB", 100)
- -- addRule(1000 , "opencomputers:material" , 6 , "Transistor", 200)
- -- addRule(200 , "opencomputers:material" , 7 , "Chip1", 100)
- -- addRule(20 , "opencomputers:material" , 8 , "Chip2", 20)
- -- addRule(10 , "opencomputers:material" , 9 , "Chip3", 10)
- -- addRule(1024, "projectred-core:resource_item", 0 , "Circuit Plate", 300)
- -- addRule(500 , "mekanism:controlcircuit" , 0 , "Basic Control Circuit", 200)
- -- addRule(100 , "mekanism:controlcircuit" , 1 , "Adv Control Circuit", 50)
- -- addRule(20 , "mekanism:controlcircuit" , 2 , "Elite Control Circuit", 10)
- -- addRule(2 , "mekanism:controlcircuit" , 3 , "Ultim Control Circuit", 2)
- -- addRulesWiggle("Plate", 10, 10)
- -- addRulesWiggle("Ingot", 20, 20)
- -- saveConfig()
- end
- -- Imports
- local component = require("component")
- local sides = require("sides")
- local term = require("term")
- local event = require("event")
- local meController = component.me_controller
- local invController = component.inventory_controller
- local RSController = component.redstone
- -- Utilities
- function mysplit (inputstr, sep)
- if inputstr == nil then return {} end
- if sep == nil then
- sep = "%s"
- end
- local t={}
- for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
- table.insert(t, str)
- end
- return t
- end
- -- Actual code
- term.clear()
- tasks = {}
- function readChest()
- print("Reading chest...")
- b = false
- for side= 0, 5 do
- n = invController.getInventorySize(side)
- print(sides[side].." : "..(n or "nil"))
- if n then
- for i = 1, n do
- it=invController.getStackInSlot(side, i)
- if it then print(it.name.."/"..it.damage) b = true end
- end
- end
- end
- if b then os.sleep(2) end
- end
- function checkAvailableCPUs()
- meCpus = meController.getCpus()
- local occupiedCpus = 0
- acpus = 0
- for cpuIndex = 1, #meCpus do
- -- if not meCpus[cpuIndex].busy then table.insert(acpus, meCpus[cpuIndex]) end
- if not meCpus[cpuIndex].busy then acpus = acpus+1 end
- end
- return acpus
- end
- function checkIfTasksEnded()
- i = 1
- while i <= #tasks do
- t = tasks[i]
- tt = t.task
- -- for i, t in pairs(tasks) do
- -- tt = t.task
- if tt.isDone() then
- table.remove(tasks, i)
- print("Task finished: "..t.label)
- elseif tt.isCanceled() then
- table.remove(tasks, i)
- print("!! Task canceled: "..t.label.." !!")
- else
- print("Task running: "..t.label)
- i = i + 1
- end
- end
- end
- function printStock(verbose)
- l = 0
- for _, rule in pairs(rules) do
- if rule["dmg"] then
- meItems = meController.getItemsInNetwork({ name = rule["name"], damage = rule["dmg"]})
- else
- meItems = meController.getItemsInNetwork({ name = rule["name"]})
- end
- if meItems.n == 0 then
- print("Could not find "..rule["name"].."/"..(rule["dmg"] or "*"))
- l = l + 1
- if l > screenSize then os.sleep(2) l = 0 end
- goto nextRule
- end
- if meItems.n == 1 then
- 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
- 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
- else
- if (verbose == "all") then print(rule["name"].."/"..(rule["dmg"] or "*")) end
- for i=1, meItems.n do
- it = meItems[i]
- 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
- 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
- end
- end
- ::nextRule::
- end
- end
- function checkItemsAndCraft(cpus)
- l = 0
- for _, rule in pairs(rules) do
- if rule["count"] > 0 then -- count == 0 if disabled
- if rule["dmg"] then -- Some items don't use dmg as sub item id, mainly vanilla items
- meItems = meController.getItemsInNetwork({ name = rule["name"], damage = rule["dmg"]})
- else
- meItems = meController.getItemsInNetwork({ name = rule["name"]})
- end
- if meItems.n == 0 then
- print("Could not find "..rule["name"].."/"..(rule["dmg"] or "*"))
- l = l + 1
- if l > screenSize then os.sleep(2) l = 0 end
- else
- for i=1, meItems.n do -- usually only 1 item found. Can be more is no "damage" is specified
- it = meItems[i]
- result = orderMissingItem(cpus, it, rule["count"], rule["limit"])
- -- if result ~= -1 then print(rule["label"].." returned "..result) end
- if (result == 3) or (result == 4) then return end -- no need to continue.
- end
- end
- os.sleep(0)
- end
- end
- end
- -- Return values:
- -- Only 3 and 4 return values are used to exit the rules loop.
- -- -1 Nothing to do
- -- 0 success
- -- 1 already running
- -- 2 missing ingredients
- -- 3 max tasks reached
- -- 4 max CPUs reached
- -- 5 No recipe
- function orderMissingItem(cpus, item, target, limit)
- -- checks --
- if #tasks >= maxTasks then print("Max concurent tasks reached.") return 3 end
- if cpus <= 1 then print("No CPU available.") return 4 end
- if item.size >= target then return -1 end
- -- Are we already crafting this ?
- for _, t in pairs(tasks) do
- if (t.name == item.name) and (t.dmg == item.damage) then
- print("Already crafting ".. item.label)
- return 1
- end
- end
- -- print("Trying to order "..item.name.."/"..item.damage)
- -- Try to rder the craft
- needed = math.min(limit, target - item.size)
- craftables = meController.getCraftables({ name = item.name, damage = item.damage})
- if craftables.n == 0 then print("No recipe for ".. item.label) return 5 end
- for i=1, craftables.n do -- supposedly the list of available recipes for this item
- craftable = craftables[i]
- task = craftable.request(needed)
- if task.isCanceled() then
- print("Missing ingredients for "..item.label.." recipe "..i)
- else
- print("Ordered "..needed.." "..item.label.." (recipe "..i..")")
- table.insert(tasks, {name=item.name, dmg=item.damage, task=task, label=item.label})
- cpus = cpus - 1
- return 0
- end
- end
- return 2
- end
- function readConfig()
- local file,err = io.open("rules.cfg", "r")
- if err == nil then
- version = tonumber(file:read("*line"))
- if version == 2 then
- maxTasks = tonumber(file:read("*line"))
- maxTaskSize = tonumber(file:read("*line"))
- screenSize = tonumber(file:read("*line"))
- l = file:read("*line")
- while l ~= 1 and l ~= nil do
- if utf8.len(l) > 5 then
- s = mysplit(l, "\t")
- if s[3] == "*" then
- table.insert(rules, {count=tonumber(s[1]), name=s[2], label=s[4], limit=tonumber(s[5])})
- else
- table.insert(rules, {count=tonumber(s[1]), name=s[2], dmg=tonumber(s[3]), label=s[4], limit=tonumber(s[5])})
- end
- end
- l = file:read("*line")
- end
- end
- if version == 3 then
- maxTasks = tonumber(file:read("*line"))
- maxTaskSize = tonumber(file:read("*line"))
- screenSize = tonumber(file:read("*line"))
- l = file:read("*line")
- while l ~= nil and l ~= 1 and l ~= 0 do
- if utf8.len(l) > 5 then
- s = mysplit(l, "+")
- if s[3] == "*" then
- table.insert(rules, {count=tonumber(s[1]), name=s[2], label=s[4], limit=tonumber(s[5])})
- else
- table.insert(rules, {count=tonumber(s[1]), name=s[2], dmg=tonumber(s[3]), label=s[4], limit=tonumber(s[5])})
- end
- end
- l = file:read("*line")
- end
- end
- file:close()
- end
- end
- function saveConfig()
- os.execute("rm rules.bak")
- os.execute("cp rules.cfg rules.bak")
- local file,err = io.open("rules.cfg", "w")
- file:write("3\n")
- file:write(maxTasks.."\n")
- file:write(maxTaskSize.."\n")
- file:write(screenSize.."\n")
- s = ""
- for _, i in pairs(rules) do
- -- print(i.name, i.dmg)
- s = s .. (i.count.."+"..i.name.."+"..(i.dmg or "*").."+"..(i.label or "-").."+"..(i.limit or "-").."\n")
- end
- file:write(s)
- file:close()
- end
- function addRulesWiggle(name, qty, limit)
- print("Adding wiggle rule ; this is quite long!")
- craftables = meController.getCraftables()
- print(craftables.n)
- for i=1, craftables.n do
- if ((i % 100) == 0) then print(i) end
- if string.find(craftables[i].getItemStack().label, name) then
- addRule(qty, craftables[i].getItemStack().name, craftables[i].getItemStack().damage, craftables[i].getItemStack().label, limit)
- end
- end
- end
- function addRule(count, name, dmg, label, limit)
- for _, r in pairs(rules) do
- if (r.name == name ) and not r.dmg then return end
- if (r.name == name ) and ((r.dmg or -1) == dmg) then return end
- end
- table.insert(rules, {count=count, name=name, dmg=dmg, label=label, limit=limit})
- print("New rule: "..label)
- end
- -- Main loop
- -- readChest()
- buildRules()
- iter=1
- if (RSController.getInput(sides.left) ~= 0) then print("Flip the switch to the right to activate the autocrafter.\n") end
- while (RSController.getInput(sides.left) == 0) do
- -- term.clear()
- print("Iteration "..iter.. ". Flip the switch to the right to exit.\n")
- cpus = checkAvailableCPUs()
- checkIfTasksEnded()
- print(cpus.." CPUs available. "..#tasks.." Tasks running.\n")
- -- printStock("missing")
- if ((cpus > 1) and (#tasks < maxTasks))then
- checkItemsAndCraft(cpus)
- end
- print("Yielding")
- os.sleep(5)
- iter = iter +1
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement