Advertisement
Wyvern67

Snap & Box United

Jan 10th, 2016
1,287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.26 KB | None | 0 0
  1. --todo: testing + recover function line 268
  2.  
  3. local waitingTime = 0.5
  4. local lowFuelLevel = 100
  5. local refuelingColors = {2,2,2}     --for enderchest
  6. local refuelingFrequency = 777  --for tesseract
  7. local item = {}
  8. local defaultColors
  9. local temp = {}
  10. local old = {}
  11.  
  12. --Modifying the turtle's functions once again, over the turtleAPI's already modified functions
  13. --So far it didn't fuck up
  14. --Hail lua
  15.  
  16.  
  17. old.forward = turtle.forward
  18. local function forward()
  19.     while not old.forward() do
  20.         turtle.dig()
  21.         turtle.attack()
  22.     end
  23.     return true
  24. end
  25. turtle.forward = forward
  26.  
  27. old.up = turtle.up
  28. local function up()
  29.     while not old.up() do
  30.         turtle.digUp()
  31.         turtle.attackUp()
  32.     end
  33.     return true
  34. end
  35. turtle.up = up
  36.  
  37. old.down = turtle.down
  38. local function down()
  39.     while not old.down() do
  40.         turtle.digDown()
  41.         turtle.attackDown()
  42.     end
  43.     return true
  44. end
  45. turtle.down = down
  46.  
  47. old.place = turtle.place
  48. local function place()
  49.     organizeInventory()
  50.     while not old.place() do
  51.         turtle.dig()
  52.         turtle.attack()
  53.     end
  54.     return true
  55. end
  56. turtle.place = place
  57.  
  58. old.placeUp = turtle.placeUp
  59. local function placeUp()
  60.     organizeInventory()
  61.     while not old.placeUp() do
  62.         turtle.digUp()
  63.         turtle.attackUp()
  64.     end
  65.     return true
  66. end
  67. turtle.placeUp = placeUp
  68.  
  69. old.placeDown = turtle.placeDown
  70. local function placeDown()
  71.     organizeInventory()
  72.     while not old.placeDown() do
  73.         turtle.digDown()
  74.         turtle.attackDown()
  75.     end
  76.     return true
  77. end
  78. turtle.placeDown = placeDown
  79.  
  80. -- Regular functions
  81.  
  82. local function debug(str, line)
  83.     local x,y
  84.     if type(term) ~= "table" then
  85.         error("No terminal...? Wut.")
  86.     end
  87.     x,y = term.getCursorPos()
  88.     if line == nil then
  89.         term.setCursorPos(1,y)
  90.         term.clearLine(y)
  91.         term.write(tostring(str))
  92.         term.setCursorPos(x,y+1)
  93.         return true
  94.     else
  95.         term.setCursorPos(1,line)
  96.         term.clearLine(line)
  97.         term.write(tostring(str))
  98.         term.setCursorPos(x,y)
  99.         return true
  100.     end
  101. end
  102.  
  103. local function download(file)
  104.     --if not fs.exists(file) then
  105.         if not fs.exists("dl") then
  106.             shell.run("pastebin", "get", "jzpwtcvf", "dl")
  107.         end
  108.         shell.run("dl", file)
  109.     --end
  110. end
  111.  
  112. function arrayAdd(array, item)
  113.     if type(array) ~= "table" then
  114.         return {item}
  115.     else
  116.         array[#array+1] = item
  117.         return array
  118.     end
  119. end
  120.  
  121. function doOnce(func, ...)
  122.     local ret
  123.     local thisFunc = tostring(func)
  124.     if func == nil then
  125.         temp[thisFunc] = false
  126.         return true
  127.     end
  128.  
  129.     if not temp[thisFunc] then
  130.         ret = func(unpack(arg))
  131.     end
  132.     temp[thisFunc] = true
  133.     return ret
  134. end
  135.  
  136. function arraySearch(array,search)
  137.     for i,v in pairs(array) do
  138.         if v == search then
  139.             return i
  140.         end
  141.     end
  142.     return false
  143. end
  144.  
  145. function arrayPrint(array, recursive, indentation)
  146.     if indentation == nil then
  147.         indentation = 0
  148.     end
  149.  
  150.     for i,v in pairs(array) do
  151.         if type(v) == "table" and recursive then
  152.             arrayPrint(v, true, indentation+1)
  153.         else
  154.             print(string.rep("  ",indentation).."'"..tostring(v).."'")
  155.         end
  156.     end
  157. end
  158.  
  159. local function getInventoryItems()
  160.     local items = {}, id
  161.     for i = 1,16 do
  162.         if turtle.getItemCount(i) > 0 then
  163.             id = turtle.getItemDetail(i).name
  164.             items[i] = id
  165.         end
  166.     end
  167.     return items
  168. end
  169.  
  170. function organizeInventory(inventory)
  171.     if inventory == nil and properInventory ~= nil then
  172.         inventory = properInventory
  173.     end
  174.  
  175.     local oldSelectedSlot = turtle.getSelectedSlot()
  176.     local sortedPosition, sorted, id
  177.     while not sorted do
  178.         sorted = true --if everything goes right it stays true
  179.         for i = 1,16 do
  180.             --for each item
  181.             if turtle.getItemCount(i) > 0 then
  182.                 --if not empty, else pass this slot
  183.                 id = turtle.getItemDetail(i).name
  184.                 sortedPosition = arraySearch(inventory, id)
  185.  
  186.                 if sortedPosition then --if it has a proper position
  187.                     if i == sortedPosition then
  188.                         -- alright this one's sorted
  189.                     else
  190.                         sorted = false
  191.                         local reasonToMove = turtle.getItemCount(sortedPosition)
  192.                         if reasonToMove > 0 then
  193.                             turtle.select(sortedPosition)
  194.                             turtle.transferTo(16)
  195.                         end
  196.                         turtle.select(i)
  197.                         turtle.transferTo(sortedPosition)
  198.                         if reasonToMove > 0 then
  199.                             turtle.select(16)
  200.                             turtle.transferTo(i)
  201.                         end
  202.                         -- if it couldn't be sorted
  203.                     end
  204.                 else --if it doesn't have a proper position
  205.                     debug(tostring(id) .. " doesn't have a proper position")
  206.                     --arrayPrint(inventory)
  207.                     turtle.select(i)
  208.                     turtle.drop()
  209.                 end
  210.             end
  211.         end
  212.     end
  213.     turtle.select(oldSelectedSlot)
  214.     return true
  215. end
  216.  
  217. local function getChestColor()
  218.     local sColors, chestSlot
  219.     if tesseract then
  220.         chestSlot=2
  221.         sColors = -1
  222.     elseif enderchest then
  223.         chestSlot=3
  224.         sColors = {0,0,0}
  225.     else
  226.         return false
  227.     end
  228.  
  229.     turtle.select(chestSlot)
  230.     turtle.placeUp()
  231.     chest = peripheral.wrap("top")
  232.     assert(chest, "Could not find the enderchest/tesseract. Was it in the inventory?")
  233.  
  234.     if enderchest then
  235.         sColors[1],sColors[2],sColors[3] = chest.getColors()
  236.     else
  237.         sColors = chest.getFrequency()
  238.     end
  239.     turtle.digUp()
  240.     return sColors
  241. end
  242. getTesseractFrequency = getChestColor
  243.  
  244. function setupWell()
  245.     debug("Setting up everything...", 12)
  246.     organizeInventory()
  247.  
  248.     if enderchest then
  249.         --Placing well down
  250.         step = 0
  251.         turtle.select(1)
  252.         turtle.place()
  253.         step = 1
  254.  
  255.         --Placing chest
  256.         turtle.select(3)
  257.         turtle.up()
  258.         turtle.place()
  259.         step = 2
  260.         turtle.onEachMove()
  261.  
  262.         --Placing energy (remember to do that last)
  263.         turtle.select(2)
  264.         turtle.placeDown()
  265.         step = 3
  266.         turtle.onEachMove()
  267.     elseif not enderchest then
  268.         if turtle.z < 1 then
  269.             turtle.up()
  270.         end
  271.  
  272.         --Placing energy
  273.         step = 0
  274.         turtle.select(2)
  275.         turtle.place()
  276.         step = 1
  277.  
  278.         --Placing well
  279.         turtle.down()
  280.  
  281.         turtle.select(1)
  282.         turtle.place()
  283.         step = 3
  284.         turtle.onEachMove()
  285.     end
  286. end
  287.  
  288. function gotoHeight(z)
  289.     local success = true
  290.  
  291.     while turtle.z < z do --go z+
  292.         success = success and turtle.up()
  293.         if not success then return false end
  294.     end
  295.     while turtle.z > z do --go z-
  296.         success = success and turtle.down()
  297.         if not success then return false end
  298.     end
  299.     return success
  300. end
  301.  
  302. function recover(step)
  303.     smartRefuel()
  304.     organizeInventory()
  305.     debug("Recovering...")
  306.     debug("I was at step "..tostring(step))
  307.     if step == 4 then
  308.         if turtle.facing == "east" then
  309.             if turtle.y%2 == 0 then
  310.                 turtle.forward()
  311.             end
  312.             turtle.turnRight()
  313.             turtle.back()
  314.         elseif turtle.facing == "west" then
  315.             if turtle.y%2 == 1 then
  316.                 turtle.forward()
  317.             end
  318.             turtle.turnLeft()
  319.             turtle.back()
  320.         else
  321.             turtle.back()
  322.         end
  323.     end
  324.  
  325.     if enderchest then
  326.         --0:has everything, do nothing
  327.         --1:placed the well
  328.         --2:placed the chest
  329.         --3:placed the energy (most common)
  330.         if step == 1 then
  331.             turtle.select(1)
  332.             turtle.dig()
  333.         elseif step == 2 or step == 3 then
  334.             turtle.select(3)
  335.             turtle.dig()
  336.             turtle.select(2)
  337.             turtle.digDown()
  338.             turtle.down()
  339.         end
  340.     else --not enderchest
  341.         --0:has everything, do nothing
  342.         --1:placed the energy
  343.         --3:placed the well
  344.         if step ~= 3 and turtle.z ~= 1 then
  345.             gotoHeight(1)
  346.         end
  347.         if step == 3 and turtle.z ~= 0 then
  348.             gotoHeight(0)
  349.         end
  350.  
  351.         if step == 1 then
  352.             turtle.dig()
  353.         elseif step == 2 then
  354.             --deprecated
  355.         elseif step == 3 then
  356.             turtle.dig()
  357.             turtle.up()
  358.             turtle.dig()
  359.         end
  360.     end
  361. end
  362.  
  363. function packupWell()
  364.     debug("Packing up everything...", 12)
  365.     if enderchest then
  366.         empty()
  367.  
  368.         --Removing energy
  369.         turtle.select(2)
  370.         turtle.digDown()
  371.         step = 2
  372.         turtle.onEachMove()
  373.  
  374.         --Removing chest
  375.         turtle.select(3)
  376.         turtle.dig()
  377.         step = 1
  378.         turtle.onEachMove()
  379.  
  380.         --Removing well
  381.         turtle.down()
  382.         turtle.select(1)
  383.         turtle.dig()
  384.         step = 0
  385.         turtle.onEachMove()
  386.     else
  387.         turtle.up()
  388.         empty()
  389.  
  390.         --Removing energy
  391.         turtle.select(2)
  392.         turtle.dig()
  393.         turtle.forward()
  394.         step = 1
  395.         turtle.onEachMove()
  396.  
  397.         --Removing well
  398.         turtle.select(1)
  399.         turtle.digDown()
  400.         step = 0
  401.         turtle.onEachMove()
  402.     end
  403.     debug("Done.", 12)
  404. end
  405.  
  406. local function isImportant(name)
  407.     if arraySearch(item.importants, name) ~=  false then
  408.         return true
  409.     else
  410.         return false
  411.     end
  412. end
  413. item.isImportant = isImportant
  414.  
  415. function empty()
  416.     local name
  417.  
  418.     for i = 1,16 do
  419.         if turtle.getItemCount(i) > 0 then
  420.             name = turtle.getItemDetail(i).name
  421.             if not item.isImportant(name) then
  422.                 turtle.select(i)
  423.                 turtle.drop()
  424.             end
  425.         end
  426.     end
  427. end
  428.  
  429. function isEmpty()
  430.     local name
  431.  
  432.     for i = 1,16 do
  433.         if turtle.getItemCount(i) > 0 then
  434.             name = turtle.getItemDetail(i).name
  435.             if not item.isImportant(name) then
  436.                 return false
  437.             end
  438.         end
  439.     end
  440.     return true
  441. end
  442.  
  443. function smartRefuel()
  444.     local chestSlot
  445.     if turtle.getFuelLevel() <= lowFuelLevel then
  446.         debug("Refueling", 12)
  447.  
  448.         if tesseract == true then
  449.             chestSlot = 2
  450.         elseif enderchest == true then
  451.             chestSlot = 3
  452.         else
  453.             return false
  454.         end
  455.  
  456.         turtle.select(chestSlot)
  457.         turtle.placeUp()
  458.         empty()
  459.         while not isEmpty() do
  460.             doOnce(debug, "Inventory full and unable to unload. Waiting.", 12)
  461.             empty()
  462.             sleep(1)
  463.         end
  464.  
  465.         if enderchest == true then
  466.             chest = peripheral.wrap("top")
  467.  
  468.             debug("Problem with the enderchest. Waiting...", 12)
  469.             while type(chest) ~=  "table" or chest.setColors == nil do
  470.                 sleep()
  471.             end
  472.             debug("Refueling", 12)
  473.  
  474.             chest.setColors(unpack(refuelingColors))
  475.  
  476.             turtle.select(16)
  477.             assert(turtle.suckUp(), "Could not suck more fuel in")
  478.             turtle.refuel()
  479.  
  480.             chest.setColors(unpack(defaultColors))
  481.         end
  482.  
  483.         if tesseract == true then
  484.             chest = peripheral.wrap("top")
  485.  
  486.             debug("Problem with the tesseract. Waiting...", 12)
  487.             while type(chest) ~=  "table" or chest.setFrequency == nil do
  488.                 sleep()
  489.             end
  490.             debug("Refueling", 12)
  491.  
  492.             chest.setFrequency(refuelingFrequency)
  493.             while turtle.getFuelLevel() < 1000 do
  494.                 shell.run("refuel", "all")
  495.                 sleep()
  496.             end
  497.             chest.setFrequency(defaultFrequency)
  498.         end
  499.  
  500.         turtle.select(chestSlot)
  501.         turtle.digUp()
  502.  
  503.         if turtle.getFuelLevel() > lowFuelLevel then
  504.             return true
  505.         else
  506.             debug("Couldn't refuel")
  507.             return false
  508.         end
  509.     end
  510. end
  511.  
  512. local hasDug
  513. local function waitForWell(lapse)
  514.     if enderchest then
  515.         --Mining well is not in range
  516.         --Extrapolating when to return true from the chest's inventory
  517.         local chest = peripheral.wrap("front")
  518.         local stacks = chest.getAllStacks()
  519.  
  520.         --Verifying if the chest has items in it in the first place
  521.         --Just in case the well isn't digging at all
  522.         while #stacks == 0 and not hasDug do
  523.             doOnce(debug, "Waiting for the well to dig...", 12)
  524.             stacks = chest.getAllStacks()
  525.             sleep()
  526.         end
  527.         hasDug = true
  528.         debug("Waiting for the well to finish digging...", 12)
  529.  
  530.         --Actual waiting
  531.         local moment = os.clock()
  532.         while true do
  533.             stacks = chest.getAllStacks()
  534.             if #stacks == 0 then
  535.                 if os.clock() > moment+lapse then
  536.                     return true
  537.                 end
  538.             else
  539.                 moment = os.clock()
  540.             end
  541.             sleep()
  542.         end
  543.     else
  544.         --Mining well is in front, easy to know when it stopped
  545.         local well = peripheral.wrap("front")
  546.  
  547.         debug("The mining well isn't working", 12)
  548.         while type(well) ~= "table" or well.hasWork == nil or well.getEnergyStored == nil do
  549.             sleep()
  550.             well = peripheral.wrap("front")
  551.         end
  552.  
  553.         debug("Waiting for the well to charge...", 12)
  554.         while well.getEnergyStored == nil or well.getEnergyStored() == 0 do
  555.             sleep()
  556.         end
  557.  
  558.         debug("Waiting for the well to finish digging...", 12)
  559.         while well.hasWork() do
  560.             sleep()
  561.         end
  562.         debug("Done.", 12)
  563.     end
  564. end
  565.  
  566. local function quarry(width, length)
  567.     if width == 0 or length == 0 then
  568.         os.reboot()
  569.     end
  570.     arrayPrint(item.importants)
  571.     while turtle.y < width do
  572.         -- Checking the mod 2 of the y coordinate instead of saying
  573.         -- "mine this way then turn then mine this way then turn the other way"
  574.         -- in a single block
  575.         -- will assure that no fuck up occurs when taking over from a crashed
  576.         -- turtle
  577.         if turtle.y%2 == 0 then
  578.             -- The way forward
  579.             -- x goes from 0 to length
  580.             while turtle.x < length do
  581.                 setupWell()
  582.                 waitForWell(waitingTime) --empty for at least 1s
  583.                 packupWell()
  584.                 smartRefuel()
  585.                 if enderchest then turtle.forward() end
  586.             end
  587.  
  588.             --Turning
  589.             step = 4
  590.             debug("Changing lane...", 12)
  591.             turtle.turnRight()
  592.             turtle.forward()
  593.             turtle.turnRight()
  594.             turtle.back()
  595.             debug("Done.", 12)
  596.             step = 0
  597.             turtle.onEachMove()
  598.         else
  599.             -- The way back
  600.             -- x goes from length to 0
  601.             while turtle.x > 1 do
  602.                 setupWell()
  603.                 waitForWell(waitingTime) --empty for at least t secondes
  604.                 packupWell()
  605.                 smartRefuel()
  606.                 if enderchest then turtle.forward() end
  607.             end
  608.  
  609.             --Turning
  610.             step = 4
  611.             debug("Changing lane...", 12)
  612.             turtle.turnLeft()
  613.             turtle.forward()
  614.             turtle.turnLeft()
  615.             turtle.back()
  616.             debug("Done.", 12)
  617.             step = 0
  618.             turtle.onEachMove()
  619.         end
  620.     end
  621.     if not enderchest then
  622.         turtle.down()
  623.     end
  624.     debug("Finished digging.", 12)
  625. end
  626.  
  627. local function tableToString(array)
  628.     local ret
  629.     if type(array) == "table" then
  630.         ret = string.gsub(textutils.serialize(array), "\n", "")
  631.         return ret --cuz string.gsub returns two things (return a,b)
  632.     else
  633.         assert(false)
  634.     end
  635. end
  636.  
  637. local function stringToTable(str)
  638.     if type(str) == "string" then
  639.         return textutils.unserialize(str)
  640.     else
  641.         return false
  642.     end
  643. end
  644.  
  645. local function load()
  646.     term.clear()
  647.     term.setCursorPos(1,1)
  648.     print("The turtle seems to have terminated abruptly.")
  649.     print("Loading configuration...")
  650.     print("Oops, there was a problem while loading the config file.")
  651.     print("Please delete the config file")
  652.     -- Say there's an error before even knowing there is one
  653.     -- If there's no error, the user won't have time to see those displays
  654.     -- The following lines are instantaneous.
  655.  
  656.     config = ini.open("quarryConfig.ini")
  657.     assert(config)
  658.  
  659.     turtle.x         = tonumber(config.read("x"))
  660.     turtle.y         = tonumber(config.read("y"))
  661.     turtle.z         = tonumber(config.read("z"))
  662.     turtle.facing    = config.read("Facing")
  663.  
  664.     width            = tonumber(config.read("Width"))
  665.     length           = tonumber(config.read("Length"))
  666.  
  667.     defaultColors    = stringToTable(config.read("ChestColors"))
  668.     properInventory  = stringToTable(config.read("ProperInventory"))
  669.     item.importants  = properInventory
  670.  
  671.     step             = tonumber(config.read("Step"))
  672.  
  673.     hasDug           = config.read("HasDug")
  674.     tesseract        = config.read("Tesseract")
  675.     enderchest       = config.read("EnderChest")
  676.     defaultFrequency = config.read("DefaultFrequency")
  677.  
  678.     config.close("quarryConfig.ini")
  679.  
  680.     assert(turtle.x, turtle.x)
  681.     assert(turtle.y, turtle.y)
  682.     assert(turtle.z, turtle.z)
  683.     assert(turtle.facing, tostring(turtle.facing))
  684.     assert(width, width)
  685.     assert(length, length)
  686.     assert(properInventory)
  687.     assert(step, step)
  688.     print("Loaded successfully !")
  689.  
  690.     term.clear()
  691.     term.setCursorPos(1,1)
  692. end
  693.  
  694. local function onEachMove()
  695.     if fs.exists("quarryConfig.ini") then
  696.         fs.delete("quarryConfig.ini")
  697.         if fs.exists("quarryConfig.ini") then
  698.             assert(false)
  699.         end
  700.     end
  701.     config = ini.open("quarryConfig.ini")
  702.     config.write("Step", step)
  703.     config.write("x", turtle.x)
  704.     config.write("y", turtle.y)
  705.     config.write("z", turtle.z)
  706.     config.write("Facing", turtle.facing)
  707.     config.write("Width", width)
  708.     config.write("Length", length)
  709.     config.write("ProperInventory", tableToString(properInventory))
  710.     config.write("Tesseract", tesseract)
  711.     config.write("EnderChest", enderchest)
  712.     config.write("DefaultFrequency", defaultFrequency)
  713.     if defaultColors then
  714.         config.write("ChestColors", tableToString(defaultColors))
  715.     end
  716.     if hasDug then
  717.         config.write("HasDug", tostring(hasDug))
  718.     end
  719.     config.close("quarryConfig.ini")
  720.  
  721.     debug("x:"..tostring(turtle.x) .. "         y:"..tostring(turtle.y) .. "            z:"..tostring(turtle.z) .. "        step:"..tostring(step), 13)
  722. end
  723. turtle.onEachMove = onEachMove
  724.  
  725. download("ini")
  726. os.loadAPI("ini")
  727. download("turtleAPI")
  728. shell.run("turtleAPI")
  729.  
  730.  
  731. -- If a config exists then load it and continue where you were.
  732. if fs.exists("quarryConfig.ini") then
  733.     load()
  734.     recover(step)
  735. else --If not, proceed as normal.
  736.     properInventory = getInventoryItems()   --global
  737.     item.importants = properInventory       --global
  738.     --those won't get tossed when emptying inventory
  739.     --it won't toss any of the items in the inventory at the first startup
  740.     if #properInventory == 2 then
  741.         if turtle.getItemDetail(2) and turtle.getItemDetail(2).name == "ThermalExpansion:Tesseract" then
  742.             tesseract = true
  743.             defaultFrequency = getTesseractFrequency()
  744.         end
  745.     elseif #properInventory == 3 then
  746.         enderchest = true
  747.         defaultColors = getChestColor()     --global
  748.     else
  749.         print("Invalid number of items in the inventory at startup.")
  750.         print("The startup inventory is very important. That's how the turtle learns what items to dump and what items to keep.")
  751.         print("Please, follow these guidelines:")
  752.         print("1: mining well")
  753.         print("2: energy cell/tesseract/dimensional transceiver")
  754.         print("3: ender chest you chose to put an energy cell in 2")
  755.         while turtle.getItemCount(1) == 0 or turtle.getItemCount(2) == 0 do
  756.             sleep()
  757.         end
  758.         os.reboot()
  759.     end
  760.  
  761.     turtle.facing = "north"
  762.     turtle.x = 0
  763.     turtle.y = 0
  764.     turtle.z = 0
  765.     tArgs = {...}
  766.     if #tArgs ~=  2 then
  767.         print("usage: ")
  768.         print("quarry <length> <width>")
  769.         print("<length> is how many blocks forward, <width> is how many blocks to the right")
  770.         error()
  771.     else
  772.         width, length = unpack(tArgs)
  773.         width = tonumber(width)
  774.         length = tonumber(length)
  775.     end
  776. end
  777.  
  778. smartRefuel()
  779. quarry(width, length)
  780. fs.delete("quarryConfig.ini")
  781. debug("Program complete.", 11)
  782. assert(not fs.exists("quarryConfig.ini"))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement