Advertisement
tobast

[CC] turtleFactory

Apr 15th, 2015
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.80 KB | None | 0 0
  1. function makeEnum(vals)
  2.     -- Expects vals to be a numeric array, ie vals = {blah,blah2, ...}
  3.     out = {}
  4.     for k,v in pairs(vals) do
  5.         out[v]=k
  6.     end
  7.     return out
  8. end
  9.  
  10. --================ ASSEMBLY LINE FORMAT ================--
  11. -- Each var describes the position of a block along the production line.
  12. -- The turtle will attempt to seek those blocks on its bottom, and starts
  13. -- at position 0.
  14. INPUT_CHEST_POS = 0
  15. MF_EXTRUDE_POS = 1
  16. TEMP_CHEST_POS = 2
  17. MF_ROLL_POS = 3
  18. OUTPUT_CHEST_POS = 4
  19.  
  20. PROD_LINE_ORIENTATION = 'up' -- the direction the turtle is from the
  21.     -- production line's point of view.
  22.  
  23. --================ GENERATE RECIPES =====================--
  24. --[[ Recipe format : table 't'
  25.     * t.tool = raw | craft | mf_roll | mf_extrude
  26.     * if raw : the material is a raw material, gathered from input chest.
  27.     * if craft:
  28.         o t.recipe = 3*3 array, recipe. Values belong to recipes enum.
  29.         o Must be crafted as turtle craft.
  30.     * if mf_roll:
  31.         o Must be processed by a metal former in roll mode
  32.         o t.material : belongs to the recipes enum, to be fed to the MF
  33.     * if mf_extrude:
  34.         o Must be processed by a metal former in extrude mode
  35.         o t.material : idem mf_roll
  36. --]]
  37.  
  38. RECIPES_NAMES = { 'air','iron_plate','tin_plate','tin_casing','tin_cable',
  39.     'tin_ins_cable','re_batt','copper_cable','copper_ins_cable',
  40.     'elec_circ','iron_casing','coil','elec_motor','power_unit',
  41.     'chainsaw','drill','tin','iron','rubber','copper','redstone' }
  42.  
  43. NAMES_ENUM = makeEnum(RECIPES_NAMES)
  44.  
  45. CC_NAMES = {'','ic2.itemplateiron','ic2.itemplatetin','ic2.itemcasingtin',
  46.     'ic2.itemtincable','ic2.itemtincablei','ic2.itembatredischarged',
  47.     'ic2.itemcableo','ic2.itemcable','ic2.itempartcircuit','ic2.itemironcasing',
  48.     'ic2.itempartcoil','ic2.itempartelemotor','ic2.itempowerunit',
  49.     'ic2.itemtoolchainsaw','ic2.itemtooldrill', 'ic2.itemingottin',
  50.     'item.ingotiron','ic2.itemrubber','ic2.itemingotcopper','item.redstone'
  51. }
  52.  
  53. STACK_SIZES = {64,64,64,64,64,64,16,64,64,64,64,64,64,64,1,1,64,64,64,64,64}
  54. CRAFT_RATIO = {1,1,1,2,3,1,1,3,1,1,2,1,1,1,1,1,1,1,1,1,1}
  55.  
  56. RECIPES = {}
  57. RECIPES[NAMES_ENUM['air']] = { tool='raw' }
  58. RECIPES[NAMES_ENUM['iron_plate']] = { tool='mf_roll', material=NAMES_ENUM['iron'] }
  59. RECIPES[NAMES_ENUM['tin_plate']] = { tool='mf_roll', material=NAMES_ENUM['tin'] }
  60. RECIPES[NAMES_ENUM['tin_casing']] = { tool='mf_roll',
  61.     material=NAMES_ENUM['tin_plate'] }
  62. RECIPES[NAMES_ENUM['tin_cable']] = { tool='mf_extrude', material=NAMES_ENUM['tin'] }
  63. RECIPES[NAMES_ENUM['tin_ins_cable']] = { tool='craft', recipe={
  64.     {NAMES_ENUM['tin_cable'],NAMES_ENUM['rubber'],1},{1,1,1},{1,1,1}} }
  65. RECIPES[NAMES_ENUM['re_batt']] = { tool='craft', recipe={
  66.     {1,NAMES_ENUM['tin_ins_cable'],1},
  67.     {NAMES_ENUM['tin_casing'],NAMES_ENUM['redstone'],NAMES_ENUM['tin_casing']},
  68.     {NAMES_ENUM['tin_casing'],NAMES_ENUM['redstone'],NAMES_ENUM['tin_casing']}}}
  69. RECIPES[NAMES_ENUM['copper_cable']] = { tool='mf_extrude',
  70.     material=NAMES_ENUM['copper'] }
  71. RECIPES[NAMES_ENUM['copper_ins_cable']] = { tool='craft', recipe={
  72.     {NAMES_ENUM['copper_cable'],NAMES_ENUM['rubber'],1},{1,1,1},{1,1,1}} }
  73. RECIPES[NAMES_ENUM['elec_circ']] = { tool='craft', recipe={
  74.     {NAMES_ENUM['copper_ins_cable'],NAMES_ENUM['copper_ins_cable'],NAMES_ENUM['copper_ins_cable']},
  75.     {NAMES_ENUM['redstone'],NAMES_ENUM['iron_plate'],NAMES_ENUM['redstone']},
  76.     {NAMES_ENUM['copper_ins_cable'],NAMES_ENUM['copper_ins_cable'],NAMES_ENUM['copper_ins_cable']}}}
  77. RECIPES[NAMES_ENUM['iron_casing']] = { tool='mf_roll',
  78.     material=NAMES_ENUM['iron_plate'] }
  79. RECIPES[NAMES_ENUM['coil']] = { tool='craft', recipe={
  80.     {NAMES_ENUM['copper_cable'],NAMES_ENUM['copper_cable'],NAMES_ENUM['copper_cable']},
  81.     {NAMES_ENUM['copper_cable'],NAMES_ENUM['iron'],NAMES_ENUM['copper_cable']},
  82.     {NAMES_ENUM['copper_cable'],NAMES_ENUM['copper_cable'],NAMES_ENUM['copper_cable']}}}
  83. RECIPES[NAMES_ENUM['elec_motor']] = { tool='craft', recipe={
  84.     {1,NAMES_ENUM['tin_casing'],1},
  85.     {NAMES_ENUM['coil'],NAMES_ENUM['iron'],NAMES_ENUM['coil']},
  86.     {1,NAMES_ENUM['tin_casing'],1}}}
  87. RECIPES[NAMES_ENUM['power_unit']] = { tool='craft', recipe={
  88.     {NAMES_ENUM['re_batt'],NAMES_ENUM['copper_cable'],NAMES_ENUM['iron_casing']},
  89.     {NAMES_ENUM['re_batt'],NAMES_ENUM['elec_circ'],NAMES_ENUM['elec_motor']},
  90.     {NAMES_ENUM['re_batt'],NAMES_ENUM['copper_cable'],NAMES_ENUM['iron_casing']}}}
  91. RECIPES[NAMES_ENUM['chainsaw']] = { tool='craft', recipe={
  92.     {1,NAMES_ENUM['iron_plate'],NAMES_ENUM['iron_plate']},
  93.     {NAMES_ENUM['iron_plate'],NAMES_ENUM['iron_plate'],NAMES_ENUM['iron_plate']},
  94.     {NAMES_ENUM['power_unit'],NAMES_ENUM['iron_plate'],1}}}
  95. RECIPES[NAMES_ENUM['drill']] = { tool='craft', recipe={
  96.     {1,NAMES_ENUM['iron_plate'],1},
  97.     {NAMES_ENUM['iron_plate'],NAMES_ENUM['iron_plate'],NAMES_ENUM['iron_plate']},
  98.     {NAMES_ENUM['iron_plate'],NAMES_ENUM['power_unit'],NAMES_ENUM['iron_plate']}}}
  99. RECIPES[NAMES_ENUM['tin']] = { tool='raw' }
  100. RECIPES[NAMES_ENUM['iron']] = { tool='raw' }
  101. RECIPES[NAMES_ENUM['rubber']] = { tool='raw' }
  102. RECIPES[NAMES_ENUM['copper']] = { tool='raw' }
  103. RECIPES[NAMES_ENUM['redstone']] = { tool='raw' }
  104.  
  105. --=================== END CONSTANTS ========================--
  106.  
  107. turtlePos = -1
  108.  
  109. function goToPos(pos)
  110.     while(pos > turtlePos) do
  111.         turtle.forward()
  112.         turtlePos = turtlePos + 1
  113.     end
  114.     while(pos < turtlePos) do
  115.         turtle.back()
  116.         turtlePos = turtlePos - 1
  117.     end
  118. end
  119.  
  120. function getFromBlock(recipeId, number)
  121.     while true do
  122.         inv = peripheral.wrap('bottom')
  123.         inv.condenseItems()
  124.         nbSlots = inv.getInventorySize()
  125.         for slot=1,nbSlots do
  126.             obj = inv.getStackInSlot(slot)
  127.             if(obj ~= nil and obj.raw_name == CC_NAMES[recipeId]) then
  128.                 --Since we've condensed and we are assured that number < stackSize
  129.                 --we can safely take only from the first slot we find
  130.                 inv.pushItemIntoSlot(PROD_LINE_ORIENTATION,slot,number,1)
  131.                 return
  132.             end
  133.         end
  134.         -- We've tried the whole inventory! The item is not present
  135.         print('Missing '..RECIPES_NAMES[recipeId].." x"..number)
  136.         print('Press enter to try again...')
  137.         read()
  138.     end
  139. end
  140.  
  141. function getFirstFreeSlot(inv)
  142.     size = inv.getInventorySize()
  143.     for i=1,size do
  144.         if inv.getStackInSlot(i) == nil then
  145.             return i
  146.         end
  147.     end
  148.     print('woah, temp buffer full!')
  149.     error()
  150. end
  151.  
  152. function stashItems(fromSlot, toSlot)
  153.     goToPos(TEMP_CHEST_POS)
  154.     inv = peripheral.wrap('bottom')
  155.     if(toSlot == nil) then
  156.         toSlot = getFirstFreeSlot(inv)
  157.     end
  158.     inv.pullItemIntoSlot(PROD_LINE_ORIENTATION,fromSlot,nil,toSlot)
  159.     return toSlot
  160. end
  161.  
  162. function pushToOutput(number)
  163.     -- Pushes <number> items from #1 and puts it into output chest
  164.     goToPos(OUTPUT_CHEST_POS)
  165.    
  166.     ch = peripheral.wrap('bottom')
  167.     ch.pullItem(PROD_LINE_ORIENTATION, 1, number)
  168. end
  169.  
  170. function processInMF()
  171.     -- Assumes the turtle to be above the right MF, puts everything from #1
  172.     -- into MF and waits to take it back.
  173.  
  174.     -- MF input slot: 7 ; output slot: 2
  175.     mf = peripheral.wrap('bottom')
  176.     mf.pullItem(PROD_LINE_ORIENTATION, 1, nil, 7)
  177.     while mf.getStackInSlot(7) ~= nil or mf.getProgress() < 100 do
  178.         os.sleep(1)
  179.     end -- We're now done
  180.     mf.pushItem(PROD_LINE_ORIENTATION, 2, nil, 1)
  181. end
  182.  
  183. function craftRecipe(recipeId,number,final)
  184.     -- Crafts [number] items, then put them in the 1st slot (or at least attempts)
  185.     -- Assumes this slot is empty! Also assumes number <= stackSize
  186.     if(final == nil) then
  187.         final=false
  188.     end
  189.  
  190.     if(RECIPES[recipeId].tool == 'raw') then
  191.         if(recipeId == 1) then -- air, ie nothing
  192.             return -- We're done ;)
  193.         end
  194.  
  195.         goToPos(INPUT_CHEST_POS)
  196.         getFromBlock(recipeId,number)
  197.     elseif(RECIPES[recipeId].tool == 'craft') then
  198.         local recipe = RECIPES[recipeId].recipe
  199.         local maxProcessPack = 0
  200.         for i=1,3 do for j=1,3 do
  201.             maxProcessPack = math.max(STACK_SIZES[recipe[i][j]], maxProcessPack)
  202.         end end
  203.  
  204.         local stashSlot = nil
  205.         while number > 0 do
  206.             local tempCraftSlots = {{-1,-1,-1},{-1,-1,-1},{-1,-1,-1}}
  207.             for i=1,3 do
  208.                 for j=1,3 do
  209.                     craftRecipe(recipe[i][j],math.min(maxProcessPack,number))
  210.                     if(recipe[i][j] ~= 1) then -- not air
  211.                         goToPos(TEMP_CHEST_POS)
  212.                         tempCraftSlots[i][j]=stashItems(1)
  213.                     end
  214.                 end
  215.             end
  216.             -- subcrafts done, now assemble
  217.             goToPos(TEMP_CHEST_POS)
  218.             tempCh = peripheral.wrap('bottom')
  219.             for i=1,3 do
  220.                 for j=1,3 do
  221.                     if(recipe[i][j] ~= 1) then --not air
  222.                         tempCh.pushItem(PROD_LINE_ORIENTATION,
  223.                             tempCraftSlots[i][j], nil, i*4+j+1)
  224.                     end
  225.                 end
  226.             end
  227.             turtle.craft(maxProcessPack)
  228.            
  229.             if(number > 0) then -- Drop it in temp chest
  230.                 goToPos(TEMP_CHEST_POS)
  231.                 stashSlot = stashItems(1,stashSlot)
  232.             end
  233.             number = number - maxProcessPack -- Might be below the real number
  234.             -- but it is okay
  235.         end
  236.         if stashSlot ~= nil then -- Must get stashed items
  237.             -- Already at temp chest's pos
  238.             inv = peripheral.wrap('bottom')
  239.             inv.pushItemIntoSlot(PROD_LINE_ORIENTATION,stashSlot,nil,1)
  240.         end
  241.     elseif(RECIPES[recipeId].tool == 'mf_roll') then
  242.         craftRecipe(RECIPES[recipeId].material,
  243.                     math.ceil(number / CRAFT_RATIO[recipeId]),
  244.                     false)
  245.         -- Now we have all we want in first slot (maybe more?)
  246.         goToPos(MF_ROLL_POS)
  247.         processInMF()
  248.  
  249.         remainder = (CRAFT_RATIO[recipeId] - number % CRAFT_RATIO[recipeId]) %
  250.             CRAFT_RATIO[recipeId]
  251.         if(remainder > 0) then
  252.             pushToOutput(remainder)
  253.         end
  254.     elseif(RECIPES[recipeId].tool == 'mf_extrude') then
  255.         craftRecipe(RECIPES[recipeId].material,
  256.                     math.ceil(number / CRAFT_RATIO[recipeId]),
  257.                     false)
  258.         -- Now we have all we want in first slot (maybe more?)
  259.         goToPos(MF_EXTRUDE_POS)
  260.         processInMF()
  261.  
  262.         remainder = (CRAFT_RATIO[recipeId] - number % CRAFT_RATIO[recipeId]) %
  263.             CRAFT_RATIO[recipeId]
  264.         if(remainder > 0) then
  265.             pushToOutput(remainder)
  266.         end
  267.     end
  268.  
  269.     if(final) then
  270.         -- Drop everything into the output chest
  271.         pushToOutput(nil) -- nil : everything
  272.         goToPos(-1)
  273.     end
  274. end
  275.  
  276. function craftName(name, number)
  277.     if(NAMES_ENUM[name] == nil) then
  278.         print("Invalid name")
  279.     else
  280.         craftRecipe(NAMES_ENUM[name],number,true)
  281.     end
  282. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement