Advertisement
ben_mkiv

smeltery.lua

Dec 22nd, 2019
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.91 KB | None | 0 0
  1. component = require("component")
  2. sides = require("sides")
  3. term = require("term")
  4. event = require("event")
  5.  
  6. db = component.database
  7. gpu = component.gpu
  8.  
  9. transposer = component.proxy("308a501d-1ec1-4a87-8d98-add1c0b2cee5")
  10. smelteryDrain = sides.front
  11.  
  12. resX, resY = gpu.getResolution()
  13.  
  14. verbose = false
  15. stopme = false
  16.  
  17. --todo: account smeltery size to max inputs
  18.  
  19. function findInventory(name)
  20.     gpu.setForeground(0x969696)
  21.     for i=1,#sides do
  22.         inv = transposer.getInventoryName(i-1)
  23.         if inv ~= nil then
  24.             if inv == name then
  25.                 print("(i) found " .. inv .. " on side " .. sides[i-1])
  26.                 gpu.setForeground(0xFFFFFF)
  27.                 return (i-1)
  28.     end end end
  29.        
  30.     gpu.setForeground(0xFF8A00)
  31.     print("(!) no inventory found for '" .. name .. "'")
  32.     gpu.setForeground(0xFFFFFF)
  33.     return nil
  34. end
  35.  
  36. function readFile(file)
  37.     fd = io.open(file, "r")
  38.     local data = fd:read("*a")
  39.     fd:close()
  40.     return data
  41. end
  42.  
  43. function getFreeSlots()
  44.     emptySlots = 0
  45.     stacks = transposer.getAllStacks(smeltery).getAll()
  46.     for i=1,#stacks do
  47.         if stacks[i].size == 0 then
  48.             emptySlots = emptySlots + 1
  49.         end
  50.     end
  51.     return emptySlots
  52. end
  53.  
  54. function updateStorage()
  55.     print("updating storage stats")
  56.     for i=1,#materials do
  57.         storage = me.getItemsInNetwork({ name = materials[i].name })
  58.         if #storage > 0 then
  59.             materials[i].stored = math.floor(storage[1].size)
  60.         else
  61.             materials[i].stored = 0    
  62.         end
  63.     end
  64. end
  65.  
  66. function loadMaterials()
  67.     print("\n\n(!) reading material db")
  68.     gpu.setForeground(0x969696)
  69.    
  70.     for i=1,25 do
  71.         material = db.get(i)
  72.         if material ~= nil then
  73.             print("(i) " .. material.name .. " added")
  74.             material.slot = i
  75.             material.stored = 0
  76.             table.insert(materials, material)
  77.     end end
  78.    
  79.     gpu.setForeground(0xFFFFFF)
  80.     print("(i) "..#materials .. " materials loaded\n\n")
  81. end
  82.  
  83. function getSlot(materialName)
  84.     for i=1,#materials do
  85.         if materials[i].name == materialName then
  86.             return materials[i].slot
  87.     end end
  88.    
  89.     return nil
  90. end
  91.  
  92. function moveIngots(recipe)
  93.     ingots = transposer.getStackInSlot(ingotFormer, 1)
  94.     if ingots ~= nil and ingots.size > 0 then
  95.         if transposer.transferItem(ingotFormer, interface, ingots.size) then
  96.             gpu.setForeground(0x969696)
  97.             if verbose then print("moved " .. math.floor(ingots.size) .. " ingots to storage") end
  98.             recipe.ingots.done = math.floor(recipe.ingots.done + ingots.size)
  99.             gpu.setForeground(0xFFFFFF)
  100.         else
  101.             gpu.setForeground(0xFF0000)
  102.             print("failed to move " .. math.floor(ingots.size) .. " ingots to storage")
  103.             gpu.setForeground(0xFFFFFF)
  104.     end end
  105. end
  106.  
  107. function canCraft(recipe)
  108.     maxCraft = math.huge
  109.    
  110.     for i=1,#recipe.input do
  111.         for m=1,#materials do
  112.             if materials[m].name == recipe.input[i].name then
  113.                 c = math.floor(materials[m].stored / recipe.input[i].count)
  114.                 maxCraft = math.min(maxCraft, c)
  115.     end end end
  116.    
  117.     if maxCraft ~= math.huge then
  118.         return maxCraft
  119.     else
  120.         return 0
  121.     end
  122. end
  123.  
  124. function setupInterfaceSlot(recipe, slot)
  125.     gpu.setForeground(0x969696)
  126.     io.write("setting up interface for material " .. recipe.input[slot].name .. "...")
  127.     gpu.setForeground(0xFFFFFF)
  128.     recipe.input[slot].useCount = recipe.input[slot].count * recipe.amount 
  129.     dbSlot = getSlot(recipe.input[slot].name)
  130.     if slot == nil then
  131.         gpu.setForeground(0xFF0000)
  132.         io.write("no slot found for material '".. recipe.input[slot].name "'\n")
  133.         gpu.setForeground(0xFFFFFF)
  134.         return false
  135.     end    
  136.     me.setInterfaceConfiguration(slot, db.address, dbSlot, math.min(64, recipe.input[slot].useCount))
  137.     gpu.setForeground(0x00FF00)
  138.     io.write("done!\n")
  139.     gpu.setForeground(0xFFFFFF)
  140. end
  141.  
  142. function resetInterface(slot)
  143.     gpu.setForeground(0x969696)
  144.     print("resetting interface slot " .. slot)
  145.     gpu.setForeground(0xFFFFFF)
  146.     me.setInterfaceConfiguration(slot)
  147. end
  148.  
  149. function moveItemsToSmeltery(recipe)
  150.     freeSlots = smelterySize
  151.     print("transfering items to smeltery")
  152.     for i=1,#recipe.input do
  153.         setupInterfaceSlot(recipe, i)
  154.    
  155.         while recipe.input[i].useCount > 0 do
  156.             if freeSlots == 0 then
  157.                 gpu.setForeground(0x969696)
  158.                 io.write("waiting for free slots ..")
  159.                 while freeSlots == 0 do
  160.                     io.write(".")
  161.                     freeSlots = getFreeSlots()
  162.                     os.sleep(0.5)
  163.                 end
  164.                 io.write("\n")
  165.                 gpu.setForeground(0xFFFFFF)
  166.             end
  167.            
  168.             canTransfer = math.min(freeSlots, transposer.getStackInSlot(interface, i).size)
  169.             if transposer.transferItem(interface, smeltery, math.min(canTransfer, recipe.input[i].useCount), i) then
  170.                 recipe.input[i].useCount = recipe.input[i].useCount - canTransfer
  171.                 freeSlots = freeSlots - canTransfer
  172.             end
  173.         end
  174.        
  175.         resetInterface(i)
  176.      end
  177. end
  178.  
  179. function updateAlloy(recipe)
  180.     fluid = transposer.getFluidInTank(smelteryDrain)
  181.     if #fluid > 0 and fluid[1].name == recipe.fluid then
  182.         perc = math.floor(((fluid[1].amount + recipe.alloy.done) / recipe.alloy.total * 100) * 10 + 0.5) / 10
  183.         recipe.alloy.percent = perc
  184.         recipe.alloy.waiting = math.floor(fluid[1].amount)
  185.        
  186.         if recipe.alloy.waiting > 0 and recipe.alloy.total > fluid[1].amount + recipe.alloy.done then
  187.             recipe.alloy.waiting = recipe.alloy.waiting - 1 --remove 1mb from the batch to keep 1mb on bottom of the smeltery
  188.         end    
  189.     else   
  190.         recipe.alloy.waiting = 0
  191.     end
  192.    
  193.     marginRight = 50
  194.     gpu.setForeground(0xFFBD00)
  195.     gpu.fill(resX-marginRight, 3, marginRight, 1, " ")
  196.     gpu.set(resX-marginRight, 3, recipe.alloy.percent .. "%")
  197.     gpu.set(resX-marginRight+10, 3, "("..(recipe.alloy.done + recipe.alloy.waiting).."mB of "..recipe.alloy.total.."mB)");
  198.     gpu.setForeground(0xFFFFFF)
  199. end
  200.  
  201. function moveAlloy(recipe)
  202.     if recipe.alloy.waiting < 144 and recipe.alloy.waiting + recipe.alloy.done < recipe.alloy.total then return false; end 
  203.     transfer = math.min(8000, recipe.alloy.waiting)
  204.     if transposer.transferFluid(smelteryDrain, ingotFormer, transfer) then
  205.         if verbose then print("moved " .. transfer .. "mB of alloy to ingot former") end
  206.         recipe.alloy.done = recipe.alloy.done + transfer
  207.     else
  208.         gpu.setForeground(0xFF0000)
  209.         print("failed to move " .. transfer .. "mB of alloy to ingot former")
  210.         gpu.setForeground(0xFFFFFF)
  211.     end
  212. end
  213.  
  214. function updateIngots(recipe)
  215.     marginRight = 50   
  216.     gpu.setForeground(0xFFBD00)
  217.     gpu.fill(resX-marginRight, 5, marginRight, 1, " ")
  218.     gpu.set(resX-marginRight, 5, math.floor(recipe.ingots.done/recipe.ingots.total * 100) .. "%")
  219.     gpu.set(resX-marginRight+10, 5, "("..recipe.ingots.done.." of "..recipe.ingots.total.." ingots done)");
  220.     gpu.setForeground(0xFFFFFF)
  221. end
  222.  
  223. function craftRecipe(recipe, amount)
  224.     recipe.amount = amount
  225.     recipe.alloy = { done = 0, percent = 0, waiting = 0, total = (recipe.output.count * recipe.amount * 144) }
  226.     recipe.ingots = { total = (recipe.output.count * amount), done = 0 }
  227.            
  228.     term.clear()
  229.     print("\n### crafting: "..recipe.output.count .. "x " .. recipe.output.name.." ###\n")
  230.    
  231.     if recipe.input_fluids ~= nil then
  232.         for i=1,#recipe.input_fluids do
  233.             print("please add " .. (recipe.input_fluids[i].amount * amount) .. "mB of " .. recipe.input_fluids[i].name)
  234.         end
  235.     end
  236.    
  237.     moveItemsToSmeltery(recipe)
  238.    
  239.     print("waiting for alloy")
  240.     repeat
  241.         updateAlloy(recipe)
  242.         moveAlloy(recipe)      
  243.         moveIngots(recipe)     
  244.         updateIngots(recipe)       
  245.         os.sleep(0.5)  
  246.     until recipe.alloy.done >= recipe.alloy.total and recipe.ingots.done >= recipe.ingots.total
  247.    
  248.     os.sleep(1)
  249.     updateStorage()
  250. end
  251.  
  252. function deposeLiquid()
  253.     transposer.transferFluid(smelteryDrain, ingotFormer, 16000)
  254. end
  255.  
  256. function castLiquid()
  257.     term.clear()
  258.     fluid = transposer.getFluidInTank(smelteryDrain)
  259.     if #fluid == 0 then return false; end
  260.  
  261.     fakeRecipe = {}
  262.     fakeRecipe.alloy = { done = 0, percent = 0, waiting = 0, total = math.min(math.floor(fluid[1].amount / 144) * 144, 15984) }
  263.     fakeRecipe.ingots = { done = 0, total = math.floor(fakeRecipe.alloy.total / 144) }
  264.     fakeRecipe.ingots.done = 0
  265.     fakeRecipe.fluid = fluid[1].name
  266.    
  267.     if fakeRecipe.ingots == 0 then
  268.         gpu.setForeground(0xFFC900)
  269.         print("theres not enough liquid left to cast a ingot")
  270.         gpu.setForeground(0xFFFFFF)
  271.         os.sleep(2)
  272.         return;
  273.     end
  274.    
  275.     transposer.transferFluid(smelteryDrain, ingotFormer, fakeRecipe.alloy.total)   
  276.     print("casting ".. fakeRecipe.ingots.total .. " ingots from " .. fakeRecipe.fluid)
  277.     gpu.setForeground(0x969696)
  278.     while fakeRecipe.ingots.done < fakeRecipe.ingots.total do
  279.         moveIngots(fakeRecipe)
  280.         io.write(".")
  281.         os.sleep(1)
  282.     end
  283.     gpu.setForeground(0xFFFFFF)
  284.    
  285.     gpu.setForeground(0x00FF00)
  286.     print("")
  287.     print("done!")
  288.     gpu.setForeground(0xFFFFFF)
  289.     os.sleep(1)
  290.    
  291.     fluid = transposer.getFluidInTank(smelteryDrain)
  292.     if #fluid > 0 and fluid[1].name == fakeRecipe.fluid then
  293.         print("theres fluid left, starting another run")
  294.         os.sleep(2)
  295.         castLiquid()
  296.     end
  297. end
  298.  
  299. term.clear()
  300.  
  301. print("(!) setting up devices")
  302. me = component.me_interface
  303.  
  304. ingotFormer = findInventory("nuclearcraft:ingot_former_active")
  305. if ingotFormer == nil then ingotFormer = findInventory("nuclearcraft:ingot_former_idle") end
  306.  
  307. smeltery = findInventory("tconstruct:smeltery_controller")
  308. interface = findInventory("appliedenergistics2:interface")
  309. materials = {}
  310.  
  311. smelterySize = transposer.getInventorySize(smeltery)
  312.  
  313. recipes = require("serialization").unserialize(readFile("/home/smeltery.recipes"))
  314.  
  315. loadMaterials()
  316. updateStorage()
  317.  
  318. print("\n\ninit done! press [enter] to continue...")
  319. io.read()
  320. os.sleep(0.5)
  321.  
  322.  
  323. while not stopme do
  324.     term.clear()
  325.     if verbose then verboseText = "true"; else verboseText = "false"; end
  326.     print("### select alloy/command ### (verbose: " .. verboseText .. ")\n")
  327.     for i=1,#recipes do
  328.         io.write("#" .. i .. ": " .. recipes[i].output.count .. "x " .. recipes[i].output.name .. ", ")    
  329.         maxCraft = canCraft(recipes[i])
  330.         if maxCraft > 0 then
  331.             gpu.setForeground(0x00FF00)
  332.             print("can craft "..maxCraft.." times ("..(maxCraft * recipes[i].output.count).." ingots)")
  333.         else
  334.             gpu.setForeground(0xFF0000)
  335.             print("cant craft")
  336.         end
  337.        
  338.         gpu.setForeground(0x969696)
  339.         for j=1,#recipes[i].input do
  340.             stored = 0
  341.             for m=1,#materials do
  342.                 if materials[m].name == recipes[i].input[j].name then
  343.                     stored = materials[m].stored
  344.                 end
  345.             end
  346.             print("\t" .. recipes[i].input[j].count .. "x " .. recipes[i].input[j].name .. " ("..stored.." ingots in ME Network)")
  347.         end    
  348.        
  349.         gpu.setForeground(0xFFFFFF)
  350.     end
  351.    
  352.     print("")      
  353.     print("c: cast liquid")
  354.     print("d: depose 16b of fluid in smeltery to ingot former")
  355.     print("v: toggle verbose") 
  356.     print("u: update inventory")   
  357.     print("e: exit\n")
  358.     io.write("select recipe/command: ")
  359.     input = io.read()
  360.    
  361.     if input == "e" then
  362.         stopme = true
  363.     elseif input == "d" then
  364.         deposeLiquid()
  365.     elseif input == "c" then
  366.         castLiquid()
  367.     elseif input == "u" then
  368.         updateStorage()
  369.     elseif input == "v" then
  370.         verbose = not verbose
  371.     elseif recipes[tonumber(input)] ~= nil then
  372.         io.write("amount: ")
  373.         amount = tonumber(io.read())
  374.         if amount > 0 then
  375.             craftRecipe(recipes[tonumber(input)], math.max(1, amount))
  376.         else
  377.             print("invalid input: '"..input.."'")
  378.         end
  379.     else
  380.         print("invalid input: '"..input.."'")
  381.     end
  382. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement