Advertisement
Guest User

Untitled

a guest
Aug 19th, 2019
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 19.47 KB | None | 0 0
  1. --AutoCraft for Turtles by Microeinstein
  2.  
  3. loadfile("stdturtle")()
  4.  
  5. local help = {
  6. "Usage:",
  7. "  [-s]  Scan bottom chest without move",
  8. "  [-t]  Print only required items",
  9. "  recipeDir  Recipe folder",
  10. "  objective  Final recipe",
  11. "  [count]  Amount of items"
  12. }
  13.  
  14. args = {...}
  15.  
  16. argOnlyScan = false
  17. argOnlyReq = false
  18. argFolder = ""
  19. argFinal = ""
  20. argCount = 1
  21. for k, v in pairs(args) do
  22.     if v == "-s" then
  23.         argOnlyScan = true
  24.     elseif v == "-t" then
  25.         argOnlyReq = true
  26.     elseif argFolder == "" then
  27.         argFolder = v
  28.     elseif argFinal == "" then
  29.         argFinal = v
  30.     elseif argCount == 1 then
  31.         argCount = math.max(tonumber(v) or 0, 1)
  32.     end
  33. end
  34.  
  35. if argFolder == "" or argFinal == "" then
  36.     term.more(table.concat(help, "\n"))
  37.     return
  38. end
  39.  
  40. nonil = { count = 0, name = "", damage = 0, lock = false }
  41. files = {}              --[path]    = "content"
  42. recipes = {}            --[name~damage] = {recipe1, recipe2}
  43. final = nil             --recipe
  44. recipeTree = {}         --[[
  45. {
  46.     "name~damage" = {
  47.         1 = {
  48.             required = <recipe1>,
  49.             branch = {
  50.                 <loop>, ...
  51.             }
  52.         },
  53.         2 = {
  54.             required = <recipe2>,
  55.             branch = {
  56.                 <loop>, ...
  57.             }
  58.         },
  59.         "selected" = 1
  60.     }
  61. }
  62. Final point: tree[item][tree[item].selected].required
  63. ]]--
  64. objectives = {}         --[i]   = {name~damage, count, recipe}
  65. nameCache = {}          --[id]  = name
  66. items = {}              --[i]   = {name, count, damage}
  67. slots = {}              --[i]   = {name, count, damage}
  68. --noNeed = {}               --[i]   = {name, count, damage}
  69. inverseDir = false
  70. craft_debug = false
  71.  
  72. errors = {
  73.     directoryEmpty  = "%s does not have recipes",
  74.     missingUpDown   = "Expected top chest and bottom chest",
  75.     missingRecipe   = "No recipes for %s",
  76.     noOtherRecipes  = "There's no remaining recipes",
  77.     recursiveBreak  = "No recipe for %s due to recursion",
  78.     noDrop          = "Unable to free this slot",
  79.     noTake          = "Unable to take items",
  80.     noItem          = "Expected item details",
  81.     noItems         = "Chests are empty",
  82.     noRecipe        = "%s is not a recipe",
  83.     noCraft         = "Unable to craft %s",
  84.     countMinor      = "%s count (%d) is less than %d"
  85. }
  86. function stop(...)
  87.     if #arg > 0 then
  88.         term.printc(colors.white, colors.red, string.format(unpack(arg)))
  89.     end
  90.     error()
  91. end
  92. local function trace(txt, ...)
  93.     if craft_debug then
  94.         term.pausec(colors.white, colors.green, txt.."("..table.concat(arg, ",")..")")
  95.     end
  96. end
  97.  
  98. --Recipes
  99. function recipeID(recipe)
  100.     return getID(recipe.F)
  101. end
  102. function findRecipeGroup(ID)
  103.     local p1, p2 = getNameDamage(ID)
  104.     local _, rv = table.first(recipes,
  105.         function(rID,rec,nam,dam)
  106.             local knam, kdam = getNameDamage(rID)
  107.             return knam == nam and (dam == nil or kdam == dam)
  108.         end, p1, p2)
  109.     return rv
  110. end
  111. function recipeToXY(num)
  112.     return math.numToXY(num, 3)
  113. end
  114. function isNeedSlot(k)
  115.     return k ~= "F" and k ~= "w" and k ~= "h"
  116. end
  117. function fixRecipe(recipe)
  118.     local minimal = recipe ~= nil and recipe.F ~= nil and (
  119.         recipe[1] ~= nil or
  120.         recipe[2] ~= nil or
  121.         recipe[3] ~= nil or
  122.         recipe[4] ~= nil or
  123.         recipe[5] ~= nil or
  124.         recipe[6] ~= nil or
  125.         recipe[7] ~= nil or
  126.         recipe[8] ~= nil or
  127.         recipe[9] ~= nil
  128.     )
  129.     if minimal then
  130.         for i=1, 9 do
  131.             recipe[i] = recipe[i] or nonil
  132.         end
  133.     end
  134.     return minimal
  135. end
  136. function isRecipeComplete(recipe, amount)
  137.     trace("isRecipeComplete",recipe,amount)
  138.     local m = math.max(recipe.w, recipe.h)
  139.     local lowered = amount
  140.     for y=1, recipe.h do
  141.         for x=1, recipe.w do
  142.             local item = turtle.getItemDetailXY(x, y)
  143.             local slot = math.xyToNum(x, y, m)
  144.             local required = recipe[slot]
  145.             if item then
  146.                 if not (item.name == required.name and (not required.lock or item.damage == required.damage)) then
  147.                     return false
  148.                 elseif item.count < required.count / recipe.F.count * amount then
  149.                     lowered = math.min(lowered, amount - ((amount / recipe.F.count * required.count) - item.count))
  150.                 end
  151.             elseif required.count > 0 and required.name ~= "" then
  152.                 return false
  153.             end
  154.         end
  155.     end
  156.     return lowered == amount or lowered
  157. end
  158. function requiredItems(recipe, amount)
  159.     local required = {}
  160.     local ID
  161.     for k, item in pairs(recipe) do
  162.         if isNeedSlot(k) and (not string.isBlank(item.name)) and item.count > 0 then
  163.             ID = getID(item)
  164.             required[ID] = (required[ID] or 0) + math.ceil(item.count / recipe.F.count * amount)
  165.         end
  166.     end
  167.     return required
  168. end
  169. function missingItems(required)
  170.     local missing = {}
  171.     for item, count in pairs(required) do
  172.         local p1, p2 = getNameDamage(item)
  173.         if not table.exist(items,
  174.             function(k,v,id,variant,c)
  175.                 return isNeedSlot(k) and v.name == id and v.count >= c and (variant == -1 or v.damage == variant)
  176.             end, p1, p2 or -1, count) then
  177.             missing[item] = (missing[item] or 0) + count
  178.         end
  179.     end
  180.     return missing
  181. end
  182. function loadRecipes()
  183.     local mex, obj1 = fs.readDir(argFolder, true)
  184.     if mex ~= fs.mex.okRead then
  185.         stop(mex)
  186.     end
  187.     files = obj1
  188.     print("Loading recipes...")
  189.     for path, content in pairs(files) do
  190.         local r = textutils.unserialize(content)
  191.         if fixRecipe(r) then
  192.             local id = getID(r.F)
  193.             print(string.format(" + %s", id))
  194.             local w, h = 3, 3
  195.             for x = 3, 1, -1 do
  196.                 if r[x].name == "" and r[x + 3].name == "" and r[x + 6].name == "" then
  197.                     w = w - 1
  198.                 end
  199.             end
  200.             for y = 7, 1, -3 do
  201.                 if r[y].name == "" and r[y + 1].name == "" and r[y + 2].name == "" then
  202.                     h = h - 1
  203.                 end
  204.             end
  205.             r.w = w
  206.             r.h = h
  207.            
  208.             recipes[id] = recipes[id] or {}
  209.             table.insert(recipes[id], r)
  210.            
  211.             if fs.getName(path) == argFinal then
  212.                 final = r
  213.             end
  214.         else
  215.             print(string.format(" - "..errors.noRecipe, fs.getName(path)))
  216.         end
  217.     end
  218.     if table.len(recipes) == 0 then
  219.         stop(errors.directoryEmpty, argFolder)
  220.     end
  221.     if not final then
  222.         stop(fs.mex.notFound..": %s", argFinal)
  223.     end
  224. end
  225.  
  226. --Logistic
  227. function getID(details)
  228.     local r = details.name
  229.     --If lock doesn't exist (for items), else its value
  230.     if details.lock == nil or details.lock then
  231.         r = r.."~"..details.damage
  232.     end
  233.     return r;
  234. end
  235. function getNameDamage(ID)
  236.     local p1, p2 = unpack(string.split(ID, "~"))
  237.     return p1, tonumber(p2)
  238. end
  239. function getShortName(ID)
  240.     if not nameCache[ID] then  
  241.         local colon = string.split(ID, ":")
  242.         local dot = string.split(colon[2], ".")
  243.         local underscore = string.split(dot[#dot], "_")
  244.         underscore[#underscore] = string.replace(underscore[#underscore], "~", ":")
  245.         local long = {}
  246.         for k, v in pairs(underscore) do
  247.             if #v > 1 then
  248.                 table.insert(long, (#long > 0) and string.firstUpper(v) or v)
  249.             end
  250.         end
  251.         nameCache[ID] = string.format("%s %s", colon[1], table.concat(long))
  252.     end
  253.     return nameCache[ID]
  254. end
  255. function findItems(tabl, name, damage)
  256.     local rv = table.where(tabl,
  257.         function(k,v,nam,dam)
  258.             return v.name == nam and (v.lock == false or dam == nil or v.damage == dam)
  259.         end, name, damage)
  260.     return rv
  261. end
  262. function moveUp()
  263.     print("Moving items up...")
  264.     local get
  265.     repeat
  266.         get = turtle.suckDown()
  267.         if get and not turtle.dropUp() then
  268.             stop(errors.noDrop)
  269.         end
  270.     until not get
  271. end
  272. function moveDown()
  273.     print("Moving items down...")
  274.     local get
  275.     repeat
  276.         get = turtle.suckUp()
  277.         if get and not turtle.dropDown() then
  278.             stop(errors.noDrop)
  279.         end
  280.     until not get
  281. end
  282. function emptySlots()
  283.     print("Freeing slots...")
  284.     local drop = argOnlyScan and turtle.dropDown or turtle.dropUp
  285.     for s = 1, 16 do
  286.         if turtle.getItemCount(s) > 0 then
  287.             turtle.select(s)
  288.             if not drop() then
  289.                 stop(errors.noDrop)
  290.             end
  291.         end
  292.     end
  293. end
  294. function addItem(details)
  295.     if details then
  296.         local id = getID(details)
  297.         local item = items[id]
  298.         if item then
  299.             item.count = item.count + details.count
  300.         else
  301.             items[id] = details
  302.         end
  303.     else
  304.         stop(errors.noItem)
  305.     end
  306. end
  307. function scanChest()
  308.     items = {}
  309.     --slots = {}
  310.     --noNeed = {}
  311.     print("Scanning bottom chest...")
  312.     local get, it, rcps
  313.     repeat
  314.         if not (turtle.detectUp() and turtle.detectDown()) then
  315.             stop(errors.missingUpDown)
  316.         end
  317.         get = turtle.suckDown()
  318.         if get then
  319.             it = turtle.getItemDetail()
  320.             addItem(it)
  321.             print(string.format(" + %d * %s", it.count, getShortName(getID(it))))
  322.             if not turtle.dropUp() then
  323.                 stop(errors.noDrop)
  324.             end
  325.         elseif table.len(items) == 0 then
  326.             stop(errors.noItems)
  327.         end
  328.     until not get
  329.     --Chest is scanned
  330. end
  331.  
  332. --Sorting
  333. function makeTree(ID, amount, position, remainingItems, tab)
  334.     tab = tab or 0
  335.         if amount <= 0 then
  336.             return
  337.         end
  338.     local prnt = string.format("%s%d %s", string.rep(" ", tab), amount, getShortName(ID))
  339.         if argOnlyReq then
  340.             term.pause(prnt)
  341.         else
  342.             print(prnt)
  343.             os.sleep(0.05)
  344.         end
  345.     local recipes = findRecipeGroup(ID)
  346.         if not recipes or table.len(recipes) <= 0 then
  347.             return
  348.         end
  349.     position[ID] = {}
  350.     position[ID].selected = 1
  351.     for n, recipe in pairs(recipes) do
  352.         if n > 1 then
  353.             print(string.rep(" ", tab).."-OR-")
  354.         end
  355.         local required = requiredItems(recipe, amount)
  356.         --Remove already crafted items
  357.         if not argOnlyReq then
  358.             for rID, rAM in pairs(table.copy(required, false)) do
  359.                 local requiredRecipes = findRecipeGroup(rID)
  360.                 if requiredRecipes and table.len(requiredRecipes) > 0 then
  361.                     local existent = findItems(remainingItems, getNameDamage(rID))
  362.                     if existent then
  363.                         --objDebug(existent,"exBefore")
  364.                         for _, existem in pairs(existent) do
  365.                             if existem.count > 0 then
  366.                                 local subtract = math.min(existem.count, rAM)
  367.                                 rAM = rAM - subtract
  368.                                 existem.count = existem.count - subtract
  369.                             end
  370.                             if rAM == 0 then
  371.                                 required[rID] = nil
  372.                             elseif rAM > 0 then
  373.                                 required[rID] = rAM
  374.                             else
  375.                                 stop(errors.countMinor, "am", rAM, 0)
  376.                             end
  377.                         end
  378.                         --objDebug(existent,"exAfter")
  379.                     end
  380.                 end
  381.             end
  382.         end
  383.        
  384.         position[ID][n] = {
  385.             required = required,
  386.             branch = {}
  387.         }
  388.         for rID, rAM in pairs(required) do
  389.             if rID ~= ID then
  390.                 makeTree(rID, rAM, position[ID][n].branch, remainingItems, tab + 1)
  391.             else
  392.                 stop(errors.recursiveBreak, ID)
  393.             end
  394.         end
  395.     end
  396. end
  397. function readTree(position)
  398.     local total = {}
  399.     --tree[item][tree[item].selected].required
  400.     for _, combos in pairs(position) do
  401.         local combo = combos[combos.selected]
  402.         for ID, AM in pairs(combo.required) do
  403.             if not combo.branch[ID] then
  404.                 total[ID] = (total[ID] or 0) + AM
  405.             end
  406.         end
  407.         if table.len(combo.branch) > 0 then
  408.             local branch = readTree(combo.branch)
  409.             for ID, AM in pairs(branch) do
  410.                 total[ID] = (total[ID] or 0) + AM
  411.             end
  412.         end
  413.     end
  414.     return total
  415. end
  416. function nextBranch(position)
  417.     local length = table.len(position)
  418.     local at = 0
  419.     for ID, combos in pairs(position) do
  420.         at = at + 1
  421.         local combo = combos[combos.selected]
  422.         --If combo has other combinations
  423.         if table.len(combo.branch) > 0 then
  424.             if nextBranch(combo.branch) then
  425.                 return true
  426.             end
  427.         end
  428.         combos.selected = combos.selected + 1
  429.         if combos.selected >= table.len(combos) then
  430.             combos.selected = 1
  431.             if at >= length then
  432.                 return false
  433.             end
  434.         else
  435.             return true
  436.         end
  437.     end
  438. end
  439. function selectObjectives()
  440.     local req, mis
  441.     local inc = 0
  442.     while true do
  443.         inc = inc + 1
  444.         print(string.format("Checking combination %d...", inc))
  445.         req = readTree(recipeTree)
  446.         mis = missingItems(req)
  447.         if table.len(mis) > 0 then
  448.             if not nextBranch(recipeTree) then
  449.                 stop(errors.noOtherRecipes)
  450.             end
  451.         else
  452.             print("Checked and selected")
  453.             return true
  454.         end
  455.     end
  456. end
  457. function makeObjectives(branch, ID, count)
  458.     --print((branch and "table" or "nil").." "..ID.." "..count)
  459.     --[[local p1, p2 = getNameDamage(ID)
  460.     if p2 == nil then
  461.         ID = table.first(recipes,
  462.             function(k,v,id)
  463.                 local pp1, pp2 = getNameDamage(k)
  464.                 return pp1 == id
  465.             end, p1)
  466.         objDebug(ID)
  467.     end]]
  468.     local bri = branch[ID]
  469.     local sel = bri[bri.selected]
  470.     local rec = findRecipeGroup(ID)[bri.selected]
  471.     if table.len(sel.branch) > 0 then
  472.         for rid, ra in pairs(sel.required) do
  473.             local rec = findRecipeGroup(rid)
  474.             if rec and table.len(rec) > 0 then
  475.                 makeObjectives(sel.branch, rid, ra)
  476.             end
  477.         end
  478.     end
  479.     print(string.format(" > %d %s", count, getShortName(ID)))
  480.     table.insert(objectives, {
  481.         ID = ID,
  482.         count = count,
  483.         recipe = rec
  484.     })
  485. end
  486. function showRequirements()
  487.     local inc = 0
  488.     while true do
  489.         inc = inc + 1
  490.         print(string.format("COMBINATION %d:", inc))
  491.        
  492.         local requirements = readTree(recipeTree)
  493.         for rID, rAM in pairs(requirements) do
  494.             term.pause(" "..rAM.." "..getShortName(rID))
  495.         end
  496.         local otherCombos = nextBranch(recipeTree)
  497.         --fs.write("recipeTree.lua", textutils.serialise(recipeTree))
  498.         if not otherCombos then
  499.             return
  500.         end
  501.         print("\n")
  502.     end
  503. end
  504.  
  505. --Move items
  506. function slotsM(x, y, amount)
  507.     local itk, itv = table.first(slots, function(_,v,x,y) return v.x == x and v.y == y end, x, y)
  508.     if itv then
  509.         if amount then
  510.             itv.count = itv.count - amount
  511.         else
  512.             itv.count = turtle.getItemCountXY(x, y)
  513.         end
  514.         if itv.count <= 0 then
  515.             table.remove(slots, itk)
  516.         end
  517.     end
  518. end
  519. function slotsP(x, y)
  520.     local id = turtle.getItemDetailXY(x, y)
  521.     id.x = x
  522.     id.y = y
  523.     table.insert(slots, id)
  524. end
  525. function reserveSlots(recipe)
  526.     for y=1, recipe.h do
  527.         for x=1, recipe.w do
  528.             if turtle.getItemCountXY(x, y) > 0 then
  529.                 if turtle.push(x, y, inverseDir and turtle.faces.D or turtle.faces.U) then
  530.                     slotsM(x, y)
  531.                 else
  532.                     stop(errors.noDrop)
  533.                 end
  534.             end
  535.         end
  536.     end
  537. end
  538. function transportBelt(recipe)
  539.     local slots = {}
  540.     for x=4, 1, -1 do
  541.         for y=1, 4 do
  542.             if recipe.w < x or recipe.h < y then
  543.                 table.insert(slots, {x=x, y=y})
  544.             end
  545.         end
  546.     end
  547.     return slots
  548. end
  549. function roll(transport)
  550.     print("Rolling items...")
  551.     local rev = table.reverse(transport)
  552.     local to = inverseDir and turtle.faces.U or turtle.faces.D
  553.    
  554.     for n, s in pairs(rev) do
  555.         if turtle.getItemCountXY(s.x, s.y) > 0 then
  556.             if not turtle.push(s.x, s.y, to) then
  557.                 stop(errors.noDrop)
  558.             end
  559.             slotsM(s.x, s.y)
  560.         end
  561.     end
  562.     for n, s in pairs(rev) do
  563.         if not rollGetNext(s.x, s.y) then
  564.             break
  565.         end
  566.     end
  567. end
  568. function rollGetNext(x, y, recur)
  569.     recur = recur or false
  570.     if not turtle.pull(x, y, inverseDir and turtle.faces.D or turtle.faces.U) then
  571.         if recur then
  572.             return false
  573.         else
  574.             inverseDir = not inverseDir
  575.             return rollGetNext(x, y, true)
  576.         end
  577.     else
  578.         slotsP(x, y)
  579.     end
  580.     return true
  581. end
  582.  
  583. --Crafting
  584. function placeItem(slot, recipe, amount)
  585.     trace("placeItem",slot.x,slot.y,recipe.F.name,amount)
  586.     local slotK, slotItem = table.first(slots,
  587.         function(_,v,x,y) return v.x == x and v.y == y end,
  588.         slot.x, slot.y)
  589.     if not slotItem then
  590.         return
  591.     end
  592.     local requirements = findItems(table.where(recipe, isNeedSlot), slotItem.name, slotItem.damage)
  593.     if not requirements or table.len(requirements) < 1 then
  594.         return
  595.     end
  596.     local ID = getID(slotItem)
  597.     for k, required in pairs(requirements) do
  598.         local finalSlot = recipeToXY(k)
  599.         local alreadyPlaced = turtle.getItemDetailXY(finalSlot.x, finalSlot.y)
  600.         local placedCount = alreadyPlaced and alreadyPlaced.count or 0
  601.         if placedCount == 0 or ID.damage == alreadyPlaced.damage then
  602.             local moveAmount = math.min(turtle.getItemCountXY(slot.x, slot.y),
  603.                             math.ceil(amount / recipe.F.count * required.count) - placedCount)
  604.             if moveAmount > 0 then
  605.                 if items[ID].count < moveAmount then
  606.                     stop(errors.countMinor, getShortName(ID), items[ID].count, moveAmount)
  607.                 end
  608.                 if slotItem.count > 0 then
  609.                     slotItem.count = slotItem.count - moveAmount
  610.                     if not items[ID] then
  611.                         objDebug(ID,"ID")
  612.                         objDebug(items,"items")
  613.                     end
  614.                     items[ID].count = items[ID].count - moveAmount
  615.                     turtle.moveSlot(slot.x, slot.y, finalSlot.x, finalSlot.y, moveAmount)
  616.                 else
  617.                     table.remove(slots, slotK)
  618.                     break
  619.                 end
  620.                 --items[ID].count
  621.                 --elseif slotItem.count < moveAmount then
  622.                 --amount = amount - (math.ceil(amount / recipe.F.count * required.count) - placedCount)
  623.                 --objDebug(amount, "place_amount")
  624.                 --stop(errors.countMinor, getShortName(ID), items[ID].count, moveAmount)
  625.             end
  626.         end
  627.     end
  628. end
  629. function reapItems(ID, slot)
  630.     if items[ID] and items[ID].count <= 0 then
  631.         items[ID] = nil
  632.     end
  633.     slotsM(slot.x, slot.y)
  634. end
  635. function reserveCraft(recipe, amount)
  636.     print("Emptying other slots...")
  637.     for y=1, 4 do
  638.         for x=1, 4 do
  639.             if (x > recipe.w or y > recipe.h) and turtle.getItemCountXY(x, y) > 0 then
  640.                 if turtle.push(x, y, inverseDir and turtle.faces.D or turtle.faces.U) then
  641.                     slotsM(x, y)
  642.                 else
  643.                     stop(errors.noDrop)
  644.                 end
  645.             end
  646.         end
  647.     end
  648. end
  649. function craft(recipe)
  650.     turtle.setSlot(4, 1)
  651.     local fn = recipeID(recipe)
  652.     local ct = 0
  653.     repeat
  654.         local success = turtle.craft()
  655.         if success then
  656.             ct = ct + 1
  657.             for k, v in pairs(recipe) do
  658.                 if k ~= "F" and k ~= "w" and k ~= "h" then
  659.                     local ID = getID(v)
  660.                     if items[ID] then
  661.                         if items[ID].count == 0 then
  662.                             items[ID] = nil
  663.                         elseif items[ID].count < 0 then
  664.                             stop(errors.countMinor, getShortName(ID), items[ID].count, 0)
  665.                         end
  666.                     end
  667.                 end
  668.             end
  669.             addItem(turtle.getItemDetailXY(4, 1))
  670.             turtle.push(4, 1, inverseDir and turtle.faces.U or turtle.faces.D)
  671.         else
  672.             local ID = turtle.getItemDetail()
  673.             if (ID and ID.name ~= fn.name
  674.                    and ID.count ~= fn.count
  675.                    and ID.damage ~= fn.damage) or ct == 0 then
  676.                 stop(errors.noCraft, getShortName(fn))
  677.             end
  678.         end
  679.     until not success
  680. end
  681. function reAddItems(recipe)
  682.     for y=1, recipe.h do
  683.         for x=1, recipe.w do
  684.             local item = turtle.getItemDetailXY(x, y)
  685.             if item and item.count > 0 then
  686.                 addItem(item)
  687.                 if not turtle.push(x, y, inverseDir and turtle.faces.D or turtle.faces.U) then
  688.                     stop(errors.noDrop)
  689.                 end
  690.             end
  691.         end
  692.     end
  693. end
  694.  
  695. --Main
  696. function followOjectives()
  697.     trace("followOjectives")
  698.     for n, obj in pairs(objectives) do
  699.         print(string.format("Making %d %s...", obj.count, getShortName(obj.ID)))
  700.         print("Allocating slots...")
  701.         reserveSlots(obj.recipe)
  702.         followSubObjective(transportBelt(obj.recipe), obj.recipe, obj.count)
  703.         print("\n")
  704.     end
  705. end
  706. function followSubObjective(transport, recipe, count)
  707.     local complete
  708.     repeat
  709.         roll(transport)
  710.         for _, slot in pairs(transport) do
  711.             placeItem(slot, recipe, count)
  712.             reapItems(recipeID(recipe), slot)
  713.         end
  714.         complete = isRecipeComplete(recipe, count)
  715.         if not isBool(complete) then
  716.             reserveCraft(recipe, complete)
  717.             craft(recipe)
  718.             --reAddItems(recipe)
  719.             count = count - complete
  720.             complete = false
  721.         end
  722.     until complete
  723.     reserveCraft(recipe, count)
  724.     craft(recipe)
  725. end
  726. function start()
  727.     term.wash()
  728.     term.printc(colors.yellow, nil, "AutoCraft by Microeinstein")
  729.     term.printc(colors.red, nil, "Please do not edit inventories during process.")
  730.     term.printc(colors.red, nil, "Hold CTRL+T to halt")
  731.     os.sleep(1.5)
  732.    
  733.     term.printc(colors.blue, nil, "\n <Loading recipes>")
  734.     os.sleep(0.1)
  735.     loadRecipes()
  736.    
  737.     if not argOnlyReq then
  738.         term.printc(colors.blue, nil, "\n <Loading items>")
  739.         os.sleep(0.1)
  740.         emptySlots()
  741.         if not argOnlyScan then
  742.             moveUp()
  743.             moveDown()
  744.         end
  745.         scanChest()
  746.     end
  747.    
  748.     term.printc(colors.blue, nil, "\n <Building recipe tree>")
  749.     os.sleep(0.1)
  750.     makeTree(recipeID(final), argCount, recipeTree, table.copy(items, true))
  751.     --fs.write("recipeTree.lua", textutils.serialise(recipeTree))
  752.    
  753.     if argOnlyReq then
  754.         term.printc(colors.blue, nil, "\n <Showing requirements>")
  755.         os.sleep(0.1)
  756.         showRequirements()
  757.        
  758.     else
  759.         term.printc(colors.blue, nil, "\n <Finding right combination>")
  760.         os.sleep(0.1)
  761.         selectObjectives()
  762.        
  763.         term.printc(colors.blue, nil, "\n <Making crafting order>")
  764.         os.sleep(0.1)
  765.         makeObjectives(recipeTree, recipeID(final), argCount)
  766.        
  767.         term.printc(colors.green, nil, "\n <Crafting started>")
  768.         os.sleep(0.1)
  769.         followOjectives()
  770.        
  771.         term.printc(colors.green, nil, "\nSUCCESS")
  772.     end
  773. end
  774.  
  775. start()
  776. stop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement