Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --todo: testing + recover function line 268
- local waitingTime = 0.5
- local lowFuelLevel = 100
- local refuelingColors = {2,2,2} --for enderchest
- local refuelingFrequency = 777 --for tesseract
- local item = {}
- local defaultColors
- local temp = {}
- local old = {}
- --Modifying the turtle's functions once again, over the turtleAPI's already modified functions
- --So far it didn't fuck up
- --Hail lua
- old.forward = turtle.forward
- local function forward()
- while not old.forward() do
- turtle.dig()
- turtle.attack()
- end
- return true
- end
- turtle.forward = forward
- old.up = turtle.up
- local function up()
- while not old.up() do
- turtle.digUp()
- turtle.attackUp()
- end
- return true
- end
- turtle.up = up
- old.down = turtle.down
- local function down()
- while not old.down() do
- turtle.digDown()
- turtle.attackDown()
- end
- return true
- end
- turtle.down = down
- old.place = turtle.place
- local function place()
- organizeInventory()
- while not old.place() do
- turtle.dig()
- turtle.attack()
- end
- return true
- end
- turtle.place = place
- old.placeUp = turtle.placeUp
- local function placeUp()
- organizeInventory()
- while not old.placeUp() do
- turtle.digUp()
- turtle.attackUp()
- end
- return true
- end
- turtle.placeUp = placeUp
- old.placeDown = turtle.placeDown
- local function placeDown()
- organizeInventory()
- while not old.placeDown() do
- turtle.digDown()
- turtle.attackDown()
- end
- return true
- end
- turtle.placeDown = placeDown
- -- Regular functions
- local function debug(str, line)
- local x,y
- if type(term) ~= "table" then
- error("No terminal...? Wut.")
- end
- x,y = term.getCursorPos()
- if line == nil then
- term.setCursorPos(1,y)
- term.clearLine(y)
- term.write(tostring(str))
- term.setCursorPos(x,y+1)
- return true
- else
- term.setCursorPos(1,line)
- term.clearLine(line)
- term.write(tostring(str))
- term.setCursorPos(x,y)
- return true
- end
- end
- local function download(file)
- --if not fs.exists(file) then
- if not fs.exists("dl") then
- shell.run("pastebin", "get", "jzpwtcvf", "dl")
- end
- shell.run("dl", file)
- --end
- end
- function arrayAdd(array, item)
- if type(array) ~= "table" then
- return {item}
- else
- array[#array+1] = item
- return array
- end
- end
- function doOnce(func, ...)
- local ret
- local thisFunc = tostring(func)
- if func == nil then
- temp[thisFunc] = false
- return true
- end
- if not temp[thisFunc] then
- ret = func(unpack(arg))
- end
- temp[thisFunc] = true
- return ret
- end
- function arraySearch(array,search)
- for i,v in pairs(array) do
- if v == search then
- return i
- end
- end
- return false
- end
- function arrayPrint(array, recursive, indentation)
- if indentation == nil then
- indentation = 0
- end
- for i,v in pairs(array) do
- if type(v) == "table" and recursive then
- arrayPrint(v, true, indentation+1)
- else
- print(string.rep(" ",indentation).."'"..tostring(v).."'")
- end
- end
- end
- local function getInventoryItems()
- local items = {}, id
- for i = 1,16 do
- if turtle.getItemCount(i) > 0 then
- id = turtle.getItemDetail(i).name
- items[i] = id
- end
- end
- return items
- end
- function organizeInventory(inventory)
- if inventory == nil and properInventory ~= nil then
- inventory = properInventory
- end
- local oldSelectedSlot = turtle.getSelectedSlot()
- local sortedPosition, sorted, id
- while not sorted do
- sorted = true --if everything goes right it stays true
- for i = 1,16 do
- --for each item
- if turtle.getItemCount(i) > 0 then
- --if not empty, else pass this slot
- id = turtle.getItemDetail(i).name
- sortedPosition = arraySearch(inventory, id)
- if sortedPosition then --if it has a proper position
- if i == sortedPosition then
- -- alright this one's sorted
- else
- sorted = false
- local reasonToMove = turtle.getItemCount(sortedPosition)
- if reasonToMove > 0 then
- turtle.select(sortedPosition)
- turtle.transferTo(16)
- end
- turtle.select(i)
- turtle.transferTo(sortedPosition)
- if reasonToMove > 0 then
- turtle.select(16)
- turtle.transferTo(i)
- end
- -- if it couldn't be sorted
- end
- else --if it doesn't have a proper position
- debug(tostring(id) .. " doesn't have a proper position")
- --arrayPrint(inventory)
- turtle.select(i)
- turtle.drop()
- end
- end
- end
- end
- turtle.select(oldSelectedSlot)
- return true
- end
- local function getChestColor()
- local sColors, chestSlot
- if tesseract then
- chestSlot=2
- sColors = -1
- elseif enderchest then
- chestSlot=3
- sColors = {0,0,0}
- else
- return false
- end
- turtle.select(chestSlot)
- turtle.placeUp()
- chest = peripheral.wrap("top")
- assert(chest, "Could not find the enderchest/tesseract. Was it in the inventory?")
- if enderchest then
- sColors[1],sColors[2],sColors[3] = chest.getColors()
- else
- sColors = chest.getFrequency()
- end
- turtle.digUp()
- return sColors
- end
- getTesseractFrequency = getChestColor
- function setupWell()
- debug("Setting up everything...", 12)
- organizeInventory()
- if enderchest then
- --Placing well down
- step = 0
- turtle.select(1)
- turtle.place()
- step = 1
- --Placing chest
- turtle.select(3)
- turtle.up()
- turtle.place()
- step = 2
- turtle.onEachMove()
- --Placing energy (remember to do that last)
- turtle.select(2)
- turtle.placeDown()
- step = 3
- turtle.onEachMove()
- elseif not enderchest then
- if turtle.z < 1 then
- turtle.up()
- end
- --Placing energy
- step = 0
- turtle.select(2)
- turtle.place()
- step = 1
- --Placing well
- turtle.down()
- turtle.select(1)
- turtle.place()
- step = 3
- turtle.onEachMove()
- end
- end
- function gotoHeight(z)
- local success = true
- while turtle.z < z do --go z+
- success = success and turtle.up()
- if not success then return false end
- end
- while turtle.z > z do --go z-
- success = success and turtle.down()
- if not success then return false end
- end
- return success
- end
- function recover(step)
- smartRefuel()
- organizeInventory()
- debug("Recovering...")
- debug("I was at step "..tostring(step))
- if step == 4 then
- if turtle.facing == "east" then
- if turtle.y%2 == 0 then
- turtle.forward()
- end
- turtle.turnRight()
- turtle.back()
- elseif turtle.facing == "west" then
- if turtle.y%2 == 1 then
- turtle.forward()
- end
- turtle.turnLeft()
- turtle.back()
- else
- turtle.back()
- end
- end
- if enderchest then
- --0:has everything, do nothing
- --1:placed the well
- --2:placed the chest
- --3:placed the energy (most common)
- if step == 1 then
- turtle.select(1)
- turtle.dig()
- elseif step == 2 or step == 3 then
- turtle.select(3)
- turtle.dig()
- turtle.select(2)
- turtle.digDown()
- turtle.down()
- end
- else --not enderchest
- --0:has everything, do nothing
- --1:placed the energy
- --3:placed the well
- if step ~= 3 and turtle.z ~= 1 then
- gotoHeight(1)
- end
- if step == 3 and turtle.z ~= 0 then
- gotoHeight(0)
- end
- if step == 1 then
- turtle.dig()
- elseif step == 2 then
- --deprecated
- elseif step == 3 then
- turtle.dig()
- turtle.up()
- turtle.dig()
- end
- end
- end
- function packupWell()
- debug("Packing up everything...", 12)
- if enderchest then
- empty()
- --Removing energy
- turtle.select(2)
- turtle.digDown()
- step = 2
- turtle.onEachMove()
- --Removing chest
- turtle.select(3)
- turtle.dig()
- step = 1
- turtle.onEachMove()
- --Removing well
- turtle.down()
- turtle.select(1)
- turtle.dig()
- step = 0
- turtle.onEachMove()
- else
- turtle.up()
- empty()
- --Removing energy
- turtle.select(2)
- turtle.dig()
- turtle.forward()
- step = 1
- turtle.onEachMove()
- --Removing well
- turtle.select(1)
- turtle.digDown()
- step = 0
- turtle.onEachMove()
- end
- debug("Done.", 12)
- end
- local function isImportant(name)
- if arraySearch(item.importants, name) ~= false then
- return true
- else
- return false
- end
- end
- item.isImportant = isImportant
- function empty()
- local name
- for i = 1,16 do
- if turtle.getItemCount(i) > 0 then
- name = turtle.getItemDetail(i).name
- if not item.isImportant(name) then
- turtle.select(i)
- turtle.drop()
- end
- end
- end
- end
- function isEmpty()
- local name
- for i = 1,16 do
- if turtle.getItemCount(i) > 0 then
- name = turtle.getItemDetail(i).name
- if not item.isImportant(name) then
- return false
- end
- end
- end
- return true
- end
- function smartRefuel()
- local chestSlot
- if turtle.getFuelLevel() <= lowFuelLevel then
- debug("Refueling", 12)
- if tesseract == true then
- chestSlot = 2
- elseif enderchest == true then
- chestSlot = 3
- else
- return false
- end
- turtle.select(chestSlot)
- turtle.placeUp()
- empty()
- while not isEmpty() do
- doOnce(debug, "Inventory full and unable to unload. Waiting.", 12)
- empty()
- sleep(1)
- end
- if enderchest == true then
- chest = peripheral.wrap("top")
- debug("Problem with the enderchest. Waiting...", 12)
- while type(chest) ~= "table" or chest.setColors == nil do
- sleep()
- end
- debug("Refueling", 12)
- chest.setColors(unpack(refuelingColors))
- turtle.select(16)
- assert(turtle.suckUp(), "Could not suck more fuel in")
- turtle.refuel()
- chest.setColors(unpack(defaultColors))
- end
- if tesseract == true then
- chest = peripheral.wrap("top")
- debug("Problem with the tesseract. Waiting...", 12)
- while type(chest) ~= "table" or chest.setFrequency == nil do
- sleep()
- end
- debug("Refueling", 12)
- chest.setFrequency(refuelingFrequency)
- while turtle.getFuelLevel() < 1000 do
- shell.run("refuel", "all")
- sleep()
- end
- chest.setFrequency(defaultFrequency)
- end
- turtle.select(chestSlot)
- turtle.digUp()
- if turtle.getFuelLevel() > lowFuelLevel then
- return true
- else
- debug("Couldn't refuel")
- return false
- end
- end
- end
- local hasDug
- local function waitForWell(lapse)
- if enderchest then
- --Mining well is not in range
- --Extrapolating when to return true from the chest's inventory
- local chest = peripheral.wrap("front")
- local stacks = chest.getAllStacks()
- --Verifying if the chest has items in it in the first place
- --Just in case the well isn't digging at all
- while #stacks == 0 and not hasDug do
- doOnce(debug, "Waiting for the well to dig...", 12)
- stacks = chest.getAllStacks()
- sleep()
- end
- hasDug = true
- debug("Waiting for the well to finish digging...", 12)
- --Actual waiting
- local moment = os.clock()
- while true do
- stacks = chest.getAllStacks()
- if #stacks == 0 then
- if os.clock() > moment+lapse then
- return true
- end
- else
- moment = os.clock()
- end
- sleep()
- end
- else
- --Mining well is in front, easy to know when it stopped
- local well = peripheral.wrap("front")
- debug("The mining well isn't working", 12)
- while type(well) ~= "table" or well.hasWork == nil or well.getEnergyStored == nil do
- sleep()
- well = peripheral.wrap("front")
- end
- debug("Waiting for the well to charge...", 12)
- while well.getEnergyStored == nil or well.getEnergyStored() == 0 do
- sleep()
- end
- debug("Waiting for the well to finish digging...", 12)
- while well.hasWork() do
- sleep()
- end
- debug("Done.", 12)
- end
- end
- local function quarry(width, length)
- if width == 0 or length == 0 then
- os.reboot()
- end
- arrayPrint(item.importants)
- while turtle.y < width do
- -- Checking the mod 2 of the y coordinate instead of saying
- -- "mine this way then turn then mine this way then turn the other way"
- -- in a single block
- -- will assure that no fuck up occurs when taking over from a crashed
- -- turtle
- if turtle.y%2 == 0 then
- -- The way forward
- -- x goes from 0 to length
- while turtle.x < length do
- setupWell()
- waitForWell(waitingTime) --empty for at least 1s
- packupWell()
- smartRefuel()
- if enderchest then turtle.forward() end
- end
- --Turning
- step = 4
- debug("Changing lane...", 12)
- turtle.turnRight()
- turtle.forward()
- turtle.turnRight()
- turtle.back()
- debug("Done.", 12)
- step = 0
- turtle.onEachMove()
- else
- -- The way back
- -- x goes from length to 0
- while turtle.x > 1 do
- setupWell()
- waitForWell(waitingTime) --empty for at least t secondes
- packupWell()
- smartRefuel()
- if enderchest then turtle.forward() end
- end
- --Turning
- step = 4
- debug("Changing lane...", 12)
- turtle.turnLeft()
- turtle.forward()
- turtle.turnLeft()
- turtle.back()
- debug("Done.", 12)
- step = 0
- turtle.onEachMove()
- end
- end
- if not enderchest then
- turtle.down()
- end
- debug("Finished digging.", 12)
- end
- local function tableToString(array)
- local ret
- if type(array) == "table" then
- ret = string.gsub(textutils.serialize(array), "\n", "")
- return ret --cuz string.gsub returns two things (return a,b)
- else
- assert(false)
- end
- end
- local function stringToTable(str)
- if type(str) == "string" then
- return textutils.unserialize(str)
- else
- return false
- end
- end
- local function load()
- term.clear()
- term.setCursorPos(1,1)
- print("The turtle seems to have terminated abruptly.")
- print("Loading configuration...")
- print("Oops, there was a problem while loading the config file.")
- print("Please delete the config file")
- -- Say there's an error before even knowing there is one
- -- If there's no error, the user won't have time to see those displays
- -- The following lines are instantaneous.
- config = ini.open("quarryConfig.ini")
- assert(config)
- turtle.x = tonumber(config.read("x"))
- turtle.y = tonumber(config.read("y"))
- turtle.z = tonumber(config.read("z"))
- turtle.facing = config.read("Facing")
- width = tonumber(config.read("Width"))
- length = tonumber(config.read("Length"))
- defaultColors = stringToTable(config.read("ChestColors"))
- properInventory = stringToTable(config.read("ProperInventory"))
- item.importants = properInventory
- step = tonumber(config.read("Step"))
- hasDug = config.read("HasDug")
- tesseract = config.read("Tesseract")
- enderchest = config.read("EnderChest")
- defaultFrequency = config.read("DefaultFrequency")
- config.close("quarryConfig.ini")
- assert(turtle.x, turtle.x)
- assert(turtle.y, turtle.y)
- assert(turtle.z, turtle.z)
- assert(turtle.facing, tostring(turtle.facing))
- assert(width, width)
- assert(length, length)
- assert(properInventory)
- assert(step, step)
- print("Loaded successfully !")
- term.clear()
- term.setCursorPos(1,1)
- end
- local function onEachMove()
- if fs.exists("quarryConfig.ini") then
- fs.delete("quarryConfig.ini")
- if fs.exists("quarryConfig.ini") then
- assert(false)
- end
- end
- config = ini.open("quarryConfig.ini")
- config.write("Step", step)
- config.write("x", turtle.x)
- config.write("y", turtle.y)
- config.write("z", turtle.z)
- config.write("Facing", turtle.facing)
- config.write("Width", width)
- config.write("Length", length)
- config.write("ProperInventory", tableToString(properInventory))
- config.write("Tesseract", tesseract)
- config.write("EnderChest", enderchest)
- config.write("DefaultFrequency", defaultFrequency)
- if defaultColors then
- config.write("ChestColors", tableToString(defaultColors))
- end
- if hasDug then
- config.write("HasDug", tostring(hasDug))
- end
- config.close("quarryConfig.ini")
- debug("x:"..tostring(turtle.x) .. " y:"..tostring(turtle.y) .. " z:"..tostring(turtle.z) .. " step:"..tostring(step), 13)
- end
- turtle.onEachMove = onEachMove
- download("ini")
- os.loadAPI("ini")
- download("turtleAPI")
- shell.run("turtleAPI")
- -- If a config exists then load it and continue where you were.
- if fs.exists("quarryConfig.ini") then
- load()
- recover(step)
- else --If not, proceed as normal.
- properInventory = getInventoryItems() --global
- item.importants = properInventory --global
- --those won't get tossed when emptying inventory
- --it won't toss any of the items in the inventory at the first startup
- if #properInventory == 2 then
- if turtle.getItemDetail(2) and turtle.getItemDetail(2).name == "ThermalExpansion:Tesseract" then
- tesseract = true
- defaultFrequency = getTesseractFrequency()
- end
- elseif #properInventory == 3 then
- enderchest = true
- defaultColors = getChestColor() --global
- else
- print("Invalid number of items in the inventory at startup.")
- print("The startup inventory is very important. That's how the turtle learns what items to dump and what items to keep.")
- print("Please, follow these guidelines:")
- print("1: mining well")
- print("2: energy cell/tesseract/dimensional transceiver")
- print("3: ender chest you chose to put an energy cell in 2")
- while turtle.getItemCount(1) == 0 or turtle.getItemCount(2) == 0 do
- sleep()
- end
- os.reboot()
- end
- turtle.facing = "north"
- turtle.x = 0
- turtle.y = 0
- turtle.z = 0
- tArgs = {...}
- if #tArgs ~= 2 then
- print("usage: ")
- print("quarry <length> <width>")
- print("<length> is how many blocks forward, <width> is how many blocks to the right")
- error()
- else
- width, length = unpack(tArgs)
- width = tonumber(width)
- length = tonumber(length)
- end
- end
- smartRefuel()
- quarry(width, length)
- fs.delete("quarryConfig.ini")
- debug("Program complete.", 11)
- assert(not fs.exists("quarryConfig.ini"))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement