Advertisement
Ganeesya

autocraft

Mar 27th, 2015
1,097
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.29 KB | None | 0 0
  1. function working( func , ... )
  2.     local co = coroutine.create(func)
  3.     local ok,filter = coroutine.resume(co, ...)
  4.     local eve = {}
  5.  
  6.     while coroutine.status(co) ~= "dead" do
  7.  
  8.         eve = {os.pullEventRaw()}
  9.         --------------------------------
  10.         -- retuen to func
  11.         --------------------------------
  12.         if filter == nil or filter == eve[1] or eve[1] == "terminate" then
  13.  
  14.             local param
  15.             ok,param = coroutine.resume( co, unpack(eve) )
  16.             if not ok then
  17.                 error( param )
  18.             else
  19.                 filter = param
  20.             end
  21.         end
  22.  
  23.         if eve[1] == "key" and eve[2] == 20 then -- push "T" is stoping prossce
  24.             break
  25.         end
  26.     end
  27. end
  28.  
  29. function chestMatome(chesto)
  30.     local r ={}
  31.     for k, v in pairs(chesto.getAllStacks()) do
  32.         if r[v.all().raw_name] then
  33.             r[v.all().raw_name] = r[v.all().raw_name] + v.all().qty
  34.         else
  35.             r[v.all().raw_name] = v.all().qty
  36.         end
  37.     end
  38.     return r
  39. end
  40.  
  41. function sorting(chest)
  42.     local chestSide = {top="down",bottom="up"}
  43.     local data = chest.getAllStacks()
  44.     for k, v in pairs(data) do
  45.         for l, x in pairs(data) do
  46.             if k < l and v.all().raw_name == x.all().raw_name
  47.                 and v.all().raw_name ~= "" and v.all().qty < v.all().max_size
  48.                 and x.all().qty < x.all().max_size
  49.                 and not v.out and not x.out then
  50.                 chest.pushItem(chestSide[chest.side],l)
  51.                 chest.pushItem(chestSide[chest.side],k)
  52.                 data[k].out = ""
  53.                 data[l].out = ""
  54.                 if chest.side == "top" then
  55.                     turtle.dropUp()
  56.                 elseif chest.side == "bottom" then
  57.                     turtle.dropDown()
  58.                 end
  59.             end
  60.         end
  61.     end
  62. end
  63.  
  64. function recipeMatome(recipe)
  65.     local r ={}
  66.     if recipe.mat then
  67.         for k, v in pairs(recipe.mat) do
  68.             if r[v] then
  69.                 r[v] = r[v] + 1
  70.             else
  71.                 r[v] = 1
  72.             end
  73.         end
  74.     end
  75.     return r
  76. end
  77.  
  78. function haveMat(rmatome,cmatome,many)
  79.     for k, v in pairs(rmatome) do
  80.         if cmatome[k] == nil then return k,v * many end
  81.         if cmatome[k] < v * many then
  82.             return k, v * many - cmatome[k]
  83.         end
  84.     end
  85.     return nil,0
  86. end
  87.  
  88. function findRecipe(craft,book)
  89.     for k, v in pairs(book) do
  90.         if v.craft == craft then
  91.             return v
  92.         end
  93.     end
  94.     return nil
  95. end
  96.  
  97. function askMake(recipe,chest,book,many)
  98.  
  99.     local mrec = recipeMatome(recipe)
  100.     for k, v in pairs(mrec) do
  101.         if chest[k] and chest[k] >= v * many then
  102.             chest[k] = chest[k] - v * many
  103.             --write(k.."-"..v * many.." ")
  104.         else
  105.             local ask = findRecipe(k,book)
  106.             if ask then
  107.                 -- local copychest = {}
  108.                 -- for l, x in pairs(chest) do
  109.                 --  copychest[l] = x
  110.                 -- end
  111.                 local m = v * many
  112.                 -- if chest[k] then
  113.                 --  m = m - chest[k]
  114.                 -- end
  115.                 if askMake(ask,chest,book, math.ceil(m / ask.craft_many)) then
  116.                     -- for l, x in pairs(copychest) do
  117.                     --      chest[l] = x
  118.                     -- end
  119.                     -- chest = copychest
  120.                     if chest[k] then
  121.                         chest[k] = chest[k] + math.ceil(m / ask.craft_many) * ask.craft_many - m
  122.                     else
  123.                         chest[k] = math.ceil(m / ask.craft_many) * ask.craft_many - m
  124.                     end
  125.                     --write(k.."n"..m.."="..chest[k].." ")
  126.                 else
  127.                     return false
  128.                 end
  129.             else
  130.                 return false
  131.             end
  132.         end
  133.     end
  134.     return true
  135. end
  136.  
  137. function canMake(recipe,chest,book)
  138.     local mchs = chestMatome(chest)
  139.  
  140.     local can = 0
  141.     while true do
  142.         if not askMake(recipe,mchs,book,1) then
  143.             break
  144.         end
  145.         can = can + 1
  146.     end
  147.     return can
  148. end
  149.  
  150. function AllDrop(chesto)
  151.     for i = 1, 16 do
  152.         if turtle.getItemCount(i) > 0 then
  153.             turtle.select(i)
  154.             if chesto.side == "top" then
  155.                 turtle.dropUp()
  156.             elseif chesto.side == "bottom" then
  157.                 turtle.dropDown()
  158.             end
  159.         end
  160.     end
  161.     turtle.select(1)
  162. end
  163.  
  164. function autoCraft(chesto,book)
  165.     while true do
  166.         for k, v in pairs(book) do
  167.             if v.code == "recipe" then
  168.                 local ans , ansm  = haveMat(recipeMatome(v), chestMatome(chesto),1)
  169.                 if ans == nil then
  170.                     crafting(v,chesto,book,canMake(v,chesto,book))
  171.                 end
  172.             end
  173.             --sorting(chesto)
  174.             chesto.condenseItems()
  175.         end
  176.         sleep(0.1)
  177.     end
  178. end
  179.  
  180. function castCraft( recipe,chesto,book )
  181.     crafting( recipe,chesto,book,canMake(recipe,chesto,book) )
  182. end
  183.  
  184. function crafting( recipe,chesto,book,many )
  185.     --------------mat check------------------
  186.     AllDrop(chesto)
  187.  
  188.     local lmany = many
  189.     local nokori = 0
  190.     if lmany > math.floor( recipe.craft_max / recipe.craft_many ) then
  191.         nokori = many - math.floor( recipe.craft_max / recipe.craft_many )
  192.         lmany = math.floor( recipe.craft_max / recipe.craft_many )
  193.     end
  194.  
  195.     while true do
  196.         local ans,ansm = haveMat( recipeMatome(recipe), chestMatome(chesto) ,lmany)
  197.         if ans == nil then break end
  198.  
  199.         local find = false
  200.         for k, v in pairs(book) do
  201.             if v.craft == ans then
  202.                 if not crafting(v,chesto,book,math.ceil(ansm/v.craft_many)) then return false end
  203.                 find = true
  204.                 break
  205.             end
  206.         end
  207.         if not find then return false end
  208.     end
  209.  
  210.     local turtleTable = {1,2,3, 5,6,7, 9,10,11}
  211.     local chestSide = {top="down",bottom="up"}
  212.     for k, v in pairs(recipe.mat) do
  213.         loading = lmany
  214.         for l, x in pairs(chesto.getAllStacks()) do
  215.             if v == x.all().raw_name then
  216.                 loading = loading - chesto.pushItem(chestSide[chesto.side],l,loading,turtleTable[k])
  217.                 if loading == 0 then break end
  218.             end
  219.         end
  220.     end
  221.  
  222.     turtle.craft()
  223.    
  224.     AllDrop(chesto)
  225.  
  226.     if nokori > 0 then crafting( recipe,chesto,book,nokori ) end
  227.     return true
  228. end
  229.  
  230. function writeColor(str,color)
  231.     term.setTextColor(color)
  232.     write(str)
  233.     term.setTextColor(colours.white)
  234. end
  235.  
  236. function isChest( side )
  237.     if side == "top" or side == "bottom" then
  238.         if peripheral.wrap(side).getInventorySize() >= 27 then
  239.             return true
  240.         end
  241.     end
  242.     return false
  243. end
  244.  
  245. function isTable(side)
  246.     if peripheral.getType(side) == "crafters_craftingstation" then
  247.         return true
  248.     end
  249.     return false
  250. end
  251.  
  252. function init()
  253.     local periList = peripheral.getNames()
  254.     local craft = nil
  255.     local chest = nil
  256.     for k, v in pairs(periList) do
  257.         if isChest(v) then
  258.             chest = peripheral.wrap(v)
  259.             chest["side"] = v
  260.         end
  261.         if isTable(v) then
  262.             craft = peripheral.wrap(v)
  263.         end
  264.     end
  265.     if not craft or not chest then
  266.         return false,nil,nil
  267.     end
  268.     return true,craft,chest
  269. end
  270.  
  271. function checkNewRecipe( table,book )
  272.     local tabledata = table.getAllStacks()
  273.     if tabledata[1] == nil then
  274.         return false,"not recipe"
  275.     end
  276.     local newrecipe = getNewRecipe(table)
  277.     for k, v in pairs(book) do
  278.         if v.craft == newrecipe.craft then
  279.             return false,"i know"
  280.         end
  281.     end
  282.     return true
  283. end
  284.  
  285. function getNewRecipe( table )
  286.     local tabledata = table.getAllStacks()
  287.     local r = {code = "recipe",mat = {},dis_mat={},craft = "",dis_craft=""}
  288.     for k, v in pairs(tabledata) do
  289.         if k == 1 then
  290.             r.craft = v.all().raw_name
  291.             r.dis_craft = v.all().display_name
  292.             r.craft_many = v.all().qty
  293.             r.craft_max = v.all().max_size
  294.         else
  295.             r.mat[k-1] = v.all().raw_name
  296.             r.dis_mat[k-1] = v.all().display_name
  297.         end
  298.     end
  299.     return r
  300. end
  301.  
  302. function writeMatLine(recipe,pos,chest,book)
  303.     for k, v in pairs(chest) do
  304.         if recipe.mat[pos] == v.all().raw_name then
  305.             writeColor(recipe.dis_mat[pos].."\n",colours.white)
  306.             return
  307.         end
  308.     end
  309.  
  310.     for k, v in pairs(book) do
  311.         if recipe.mat[pos] == v.craft then
  312.             writeColor(recipe.dis_mat[pos].."\n",colors.yellow)
  313.             return
  314.         end
  315.     end
  316.     writeColor(recipe.dis_mat[pos].."\n",colors.red)
  317. end
  318.  
  319. function writeRecipe( recipe,chest,book )
  320.     write("craft > ".. recipe.dis_craft.."\n")
  321.     local i = 1
  322.     ----------------------------123------------------------------------
  323.     if recipe.mat[i] then writeMatLine(recipe,i,chest,book) end
  324.     i = i + 1
  325.     if recipe.mat[i] then
  326.         write("   ")
  327.         writeMatLine(recipe,i,chest,book)
  328.     end
  329.     i = i + 1
  330.     if recipe.mat[i] then
  331.         write("      ")
  332.         writeMatLine(recipe,i,chest,book)
  333.     end
  334.     i = i + 1
  335.  
  336.     ----------------------------456------------------------------------
  337.     if recipe.mat[i] then writeMatLine(recipe,i,chest,book) end
  338.     i = i + 1
  339.     if recipe.mat[i] then
  340.         write("   ")
  341.         writeMatLine(recipe,i,chest,book)
  342.     end
  343.     i = i + 1
  344.     if recipe.mat[i] then
  345.         write("      ")
  346.         writeMatLine(recipe,i,chest,book)
  347.     end
  348.     i = i + 1
  349.  
  350.     ----------------------------789------------------------------------
  351.     if recipe.mat[i] then writeMatLine(recipe,i,chest,book) end
  352.     i = i + 1
  353.     if recipe.mat[i] then
  354.         write("   ")
  355.         writeMatLine(recipe,i,chest,book)
  356.     end
  357.     i = i + 1
  358.     if recipe.mat[i] then
  359.         write("      ")
  360.         writeMatLine(recipe,i,chest,book)
  361.     end
  362. end
  363.  
  364. function addRecipeToFile(recipe)
  365.     local f = fs.open("recipes","a")
  366.     local w = ""
  367.  
  368.     for i = 1, 9 do
  369.         if recipe.mat[i] then
  370.             w = w .. recipe.mat[i] .. ","
  371.         else
  372.             w = w .. "nil,"
  373.         end
  374.     end
  375.  
  376.     for i = 1, 9 do
  377.         if recipe.mat[i] then
  378.             w = w .. recipe.dis_mat[i] .. ","
  379.         else
  380.             w = w .. "nil,"
  381.         end
  382.     end
  383.  
  384.     w = w .. recipe.craft .. "," .. recipe.dis_craft .. "," .. recipe.craft_many..","..recipe.craft_max
  385.     f.writeLine(w)
  386.     f.close()
  387. end
  388.  
  389. function split(str)
  390.     local r = {}
  391.     for v in string.gmatch(str,"[^,]+") do
  392.         r[#r+1] = v
  393.     end
  394.     write(#r)
  395.     return r
  396. end
  397.  
  398. function loadRecipe()
  399.     local r = {{code="addrecipe"},{code="reset"},{code="autocraft"},{code="search"}}
  400.     local f = fs.open("recipes","r")   
  401.     if f == nil then return r end
  402.  
  403.     local line = f.readLine()
  404.     while line do
  405.         local adds = {code = "recipe",mat = {},dis_mat={},craft = "",dis_craft=""}
  406.         local datas = split(line,"[^\,]+")
  407.         local l = 1
  408.         for i = 1, 9 do
  409.             if datas[l] ~= "nil" then
  410.                 adds.mat[i] = datas[l]
  411.             end
  412.             l = l + 1
  413.         end
  414.         for i = 1, 9 do
  415.             if datas[l] ~= "nil" then
  416.                 adds.dis_mat[i] = datas[l]
  417.             end
  418.             l = l + 1
  419.         end
  420.         adds.craft = datas[l]
  421.         l = l + 1
  422.         adds.dis_craft = datas[l]
  423.         l = l + 1
  424.         adds.craft_many = tonumber(datas[l])
  425.         l = l + 1
  426.         if datas[l] then
  427.             adds.craft_max = tonumber(datas[l])
  428.         else
  429.             adds.craft_max = 64
  430.         end
  431.         r[#r+1] = adds
  432.  
  433.         line = f.readLine()
  434.     end
  435.  
  436.     f.close()
  437.     return r
  438. end
  439.  
  440. function isHit( recipe, code )
  441.     ----------- T return for roll end hit -------------
  442.     if not recipe or recipe.code ~= "recipe" or code == "" then return true end
  443.  
  444.     if string.find( string.lower(recipe.dis_craft), string.lower(code) ) ~= nil then return true end
  445.     for k, v in pairs(recipe.dis_mat) do
  446.         if string.find( string.lower(v), string.lower(code) ) ~= nil then return true end
  447.     end
  448.     return false
  449. end
  450.  
  451. -- {code="recipe",mat={"1","2","3", "4","5","6", "7","8","9"}
  452. --      ,dis_mat={"1","2","3", "4","5","6", "7","8","9"}
  453. --      ,craft="craftans",dis_craft,craft_many,craft_max}
  454. local recipes = loadRecipe()
  455. local initans,craft,chest = init()
  456. local args = {...}
  457. local searchCode = ""
  458.  
  459. if initans then
  460.     local cursol = 1
  461.     if args[1] == "auto" then
  462.         write("startup auto crafting. PUSH T Stop.\n")
  463.         working(autoCraft,chest,recipes )
  464.         cursol = 3
  465.     end
  466.     while true do
  467.         ----------------view----------------
  468.         term.clear()
  469.         term.setCursorPos(1, 1)
  470.         if recipes[cursol].code == "addrecipe" then
  471.             local ncheck,nans = checkNewRecipe( craft, recipes )
  472.             writeColor("ADD MODE\n",colors.brown)
  473.             if ncheck then
  474.                 writeColor("ADD RECIPE : PUSH A\n",colors.green)
  475.                 writeRecipe( getNewRecipe(craft), chest.getAllStacks(), recipes )
  476.             else
  477.                 if nans == "not recipe" then
  478.                     writeColor("Its not recipe\n",colors.red)
  479.                 elseif nans == "i know" then
  480.                     writeColor("i know it\n",colors.pink)
  481.                     writeRecipe( getNewRecipe(craft), chest.getAllStacks(), recipes )
  482.                     writeColor("canmake x"..canMake(getNewRecipe(craft),chest,recipes),colors.purple)
  483.                     writeColor("\nF:Full SPACE,ENTER:Single M:Select",colours.cyan)
  484.                 end
  485.             end
  486.         elseif recipes[cursol].code == "reset" then
  487.             writeColor("RESET ALL RECIPE : PUSH R\n",colors.red)
  488.         elseif recipes[cursol].code == "autocraft" then
  489.             writeColor("AUTO CRAFTING MODE\n",colours.magenta)
  490.             writeColor("SPACE,ENTER:Start Auto Craft\n",colours.magenta)
  491.         elseif recipes[cursol].code == "search" then
  492.             writeColor("SEARCH MODE : PUSH ENTER\n",colours.cyan)
  493.             if searchCode ~= "" then
  494.                 writeColor("now code:*"..searchCode.."*\n",colors.green)
  495.             end
  496.         else
  497.             writeColor("recipe Mode ",colors.lime)
  498.             if searchCode == "" then
  499.                 write("\n")
  500.             else
  501.                 writeColor("(kw:"..searchCode..")\n",colors.lime)
  502.             end
  503.             writeRecipe( recipes[cursol], chest.getAllStacks(), recipes )
  504.             writeColor("canmake x"..canMake(recipes[cursol],chest,recipes),colors.purple)
  505.             writeColor("\nF:Full SPACE,ENTER:Single M:Select",colours.cyan)
  506.         end
  507.  
  508.         local eve = {os.pullEvent()}
  509.  
  510.         if eve[1] == "key" then
  511.             if eve[2] == 205 then -- left key
  512.                 repeat
  513.                     cursol = cursol + 1
  514.                     if cursol > #recipes then
  515.                         cursol = 1
  516.                     end
  517.                 until isHit(recipes[cursol],searchCode)
  518.             end
  519.             if eve[2] == 203 then -- right key
  520.                 repeat
  521.                     cursol = cursol - 1
  522.                     if cursol < 1 then
  523.                         cursol = #recipes
  524.                     end
  525.                 until isHit(recipes[cursol],searchCode)
  526.             end    
  527.  
  528.             if eve[2] == 28 and recipes[cursol].code == "search" then -- space key
  529.                 write(">")
  530.                 searchCode = read()
  531.                 writeColor("add search code :"..searchCode.."\n",colors.lime)
  532.                 sleep(1)
  533.             end
  534.  
  535.             ------------------------------------------------------------------------
  536.             ----------------------        recipe mode          ---------------------
  537.             ------------------------------------------------------------------------
  538.             if ( eve[2] == 57 or eve[2] == 28 ) and recipes[cursol].code == "recipe" then -- space key
  539.                 crafting( recipes[cursol],chest,recipes,1 )
  540.                 term.clear()
  541.                 term.setCursorPos(1, 1)
  542.                 writeColor("single crafting "..recipes[cursol].dis_craft.."\n",colors.lime)
  543.                 sleep(1)
  544.             end
  545.  
  546.             if eve[2] == 33 and recipes[cursol].code == "recipe" then -- f key
  547.                 working(castCraft, recipes[cursol],chest,recipes )
  548.                 term.clear()
  549.                 term.setCursorPos(1, 1)
  550.                 writeColor("full crafting "..recipes[cursol].dis_craft.."\n",colors.lime)
  551.                 sleep(1)
  552.             end
  553.  
  554.             if eve[2] == 50 and recipes[cursol].code == "recipe" then -- m key
  555.                 write("\ninput num>")
  556.                 sleep(0)
  557.                 local craftnum = tonumber(read())
  558.                 working(crafting, recipes[cursol],chest,recipes,craftnum)
  559.                 term.clear()
  560.                 term.setCursorPos(1, 1)
  561.                 writeColor("crafting "..recipes[cursol].dis_craft.."\n",colors.lime)
  562.                 sleep(1)
  563.             end
  564.  
  565.             ------------------------------------------------------------------------
  566.             ----------------------          add mode           ---------------------
  567.             ------------------------------------------------------------------------
  568.             if ( eve[2] == 57 or eve[2] == 28 ) and recipes[cursol].code == "addrecipe" and craft.getAllStacks()[1] ~= nil then -- space key
  569.                 writeColor("single crafting start\n",colors.lime)
  570.                 crafting( getNewRecipe(craft),chest,recipes,1 )
  571.                 term.clear()
  572.                 term.setCursorPos(1, 1)
  573.                 writeColor("single crafting end"..getNewRecipe(craft).dis_craft.."\n",colors.lime)
  574.                 sleep(1)
  575.             end
  576.  
  577.             if eve[2] == 33 and recipes[cursol].code == "addrecipe" and craft.getAllStacks()[1] ~= nil then -- f key
  578.                 writeColor("full crafting start\n",colors.lime)
  579.                 working(castCraft, getNewRecipe(craft),chest,recipes )
  580.                 term.clear()
  581.                 term.setCursorPos(1, 1)
  582.                 writeColor("full crafting end"..getNewRecipe(craft).dis_craft.."\n",colors.lime)
  583.                 sleep(1)
  584.             end
  585.            
  586.             if eve[2] == 50 and recipes[cursol].code == "addrecipe" then -- m key
  587.                 write("\ninput num>")
  588.                 sleep(0)
  589.                 local craftnum = tonumber(read())
  590.                 working(crafting, getNewRecipe(craft),chest,recipes,craftnum)
  591.                 term.clear()
  592.                 term.setCursorPos(1, 1)
  593.                 writeColor("crafting "..getNewRecipe(craft).dis_craft.."\n",colors.lime)
  594.                 sleep(1)
  595.             end
  596.  
  597.  
  598.             ------------------------------------------------------------------------------
  599.  
  600.             if ( eve[2] == 57 or eve[2] == 28 ) and recipes[cursol].code == "autocraft" then -- space key
  601.                 writeColor("crafting start\n",colors.lime)
  602.                 working(autoCraft,chest,recipes )
  603.                 sleep(1)
  604.                 term.clear()
  605.                 term.setCursorPos(1, 1)
  606.                 writeColor("crafting all\n",colors.lime)
  607.                 sleep(1)
  608.             end
  609.  
  610.                 -- A key
  611.             if eve[2] == 30 and recipes[cursol].code == "addrecipe" and checkNewRecipe(craft,recipes) then
  612.                 recipes[#recipes+1] = getNewRecipe(craft)
  613.                 addRecipeToFile(getNewRecipe(craft))
  614.                 writeColor("\n\nADD RECIPE\n",colors.blue)
  615.                 cursol = #recipes
  616.                 sleep(2)
  617.             end
  618.  
  619.             if eve[2] == 19 and recipes[cursol].code == "reset" then -- R key
  620.                 recipes = {{code="addrecipe"},{code="reset"}}
  621.                 fs.delete("recipes")
  622.                 cursol = 1
  623.                 writeColor("\n\nRESET RECIPE\n",colors.white)
  624.                 sleep(2)
  625.             end
  626.         end
  627.  
  628.     end
  629. else
  630.     write("need crafting station and chest, top and bottom.\n")
  631. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement