Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- ********************************************************************************** --
- -- ** OreQuarry REDUX ** --
- -- ** Minecraft Mining Turtle Ore Quarry v0.01 by Soulgriever ** --
- -- ** ** --
- -- ** Written from scratch but heavily inspired by the original OreQuarry ** --
- -- ** by AustinKK ** --
- -- ** ** --
- -- ** Instructions: ** --
- -- ** OreQuarry <X> <Z> <current Y> ** --
- -- ** ** --
- -- ** <X> and <Z> must be even numbers ** --
- -- ** ** --
- -- ** <X> How far left and right to be mined, defaultX if not specified at run ** --
- -- ** ** --
- -- ** <Z> How far forward and back to be mined, defaultX if not specified at run ** --
- -- ** ** --
- -- ** <Current Y> What layer the turtle is currently located on ** --
- -- ** Can be omitted if their is a GPS server deployed ** --
- -- ** ** --
- -- ** Slots 1-14: ** --
- -- ** blocks in these slots will be added to the blacklist and the turtle ** --
- -- ** not mine them if above or below. ***See blacklistArray*** ** --
- -- ** ** --
- -- ** Slot 15: ** --
- -- ** Optional: Fuel EnderChest ** --
- -- ** If an enderchest is found in slot 15 the turtle assumes this enderchest ** --
- -- ** contains fuel and will use items inside to refuel if low on fuel ** --
- -- ** ** --
- -- ** Optional: Fuel ** --
- -- ** Fuel can be stored here to refuel ** --
- -- ** ** --
- -- ** Slot 16: ** --
- -- ** Optional: EnderChest ** --
- -- ** If an enderchest is found in slot 16 the turtle assumes this enderchest ** --
- -- ** is for dumping ores into when the turtle's inventory fills ** --
- -- ** ** --
- -- ** Video Instructions: ** --
- -- ** **Will make one eventually** ** --
- -- ** ** --
- -- ** Change Log: ** --
- -- ** 8th Oct 2021: [v0.01] Started writing original program ** --
- -- ** TODO: ** --
- -- ** Resume support ** --
- -- ** GPS based pathfinding logic ** --
- -- ** Fix Bug that breaks program if turtle exits GPS range ** --
- -- ** ** --
- -- ** Dictionary: ** --
- -- ** _ = not done yet ** --
- -- ** * = No further changes needed at this time ** --
- -- ** ! = Major design change planned ** --
- -- ** ** --
- -- ********************************************************************************** --
- -- OreQuarry REDUX config options
- -- Set this to true to have the turtle ignore GPS servers
- gpsDisable = false
- -- Set this to true if you do not want to have the turtle broadcast updates and remain silent
- -- turtle still prints information locally
- silentMode = false
- -- Clears the generated .blacklist file before start equivilant to "delete .blacklist" and loads default values
- -- OreQuarry REDUX by default uses a dynamic .blacklist file that is updated every time the program starts but saves previous values
- clearBlacklist = false
- -- Dumps any items mined on the blacklist on the ground during checkInv()
- dumpBlacklist = true
- -- Default blacklist values ***This is ignored after a .blacklist file has been generated unless "clearBlacklist = true"***
- local blacklistArray = {
- ["minecraft:air"] = true,
- ["minecraft:bedrock"] = true,
- ["minecraft:cobblestone"] = true,
- ["minecraft:dirt"] = true,
- ["minecraft:ice"] = true,
- ["minecraft:gravel"] = true,
- ["minecraft:ladder"] = true,
- ["minecraft:sand"] = true,
- ["minecraft:snow"] = true,
- ["minecraft:snow_layer"] = true,
- ["minecraft:stone"] = true,
- ["minecraft:grass"] = true,
- ["minecraft:torch"] = true
- }
- --Initial variable values
- -- Uses these values if X and Z are not specified at program start
- -- Must be multiple of 2 (Makes mining faster and simplifies logic required)
- defaultX = 6
- defaultZ = 6
- --What Level bedrock starts at
- bedrock = 5
- -- Fuel value that the turtle views as low and attempts to refuel or returns to start of quarry
- -- may need adjusted depending on quarry size and server fuel requirements
- lowFuel = 5000
- -- Channel the turtle transmits its broadcast on
- channel = 1
- -- ********************************************************************************** --
- -- ** No Touchy below this line......Unless you want to ** --
- -- ********************************************************************************** --
- --Passes arguements specified at program start to be initialized
- local arg = { ... }
- --*Checks to see if a blacklist file has been generated, imports current blacklist, adds items in slots 1-14 to blacklist
- function checkBlacklist()
- if clearBlacklist == false then
- if fs.exists(".blacklist") then
- --Opens the .blacklist file and loads contents to blacklistArray
- local file = fs.open(".blacklist","r")
- local data = file.readAll()
- file.close()
- blacklistArray = textutils.unserialize(data)
- end
- --Compares items in slots 1-14 with blacklistArray adds item to blacklistArray if not already specified
- for i=1,14 do
- turtle.select(i)
- local item = turtle.getItemDetail()
- if item then
- if blacklistArray[item.name] then
- else
- print("Added "..item.name.." to the blacklist!")
- blacklistArray[item.name] = true
- end
- end
- end
- --Writes the updated blacklistArray to .blacklist for next run
- local file = fs.open(".blacklist","w")
- file.write(textutils.serialize(blacklistArray))
- file.close()
- turtle.select(16)
- else
- --if clearBlacklist = true deletes previous .blacklist and generates fresh list from table and turtle inventory
- fs.delete(".blacklist")
- clearBlacklist = false
- checkBlacklist()
- end
- end
- --*Attempts to suck items from inventory if turtle has inventory returns to start if not.
- function checkChest()
- if turtle.suck() == true then
- goodies = goodies+1
- checkChest()
- else
- if checkInv() > 0 then
- turtle.dig()
- goodies = goodies+1
- else
- quarryStart()
- end
- if turtle.suckUp() == true then
- goodies = goodies+1
- checkChest()
- else
- if checkInv() < 1 then
- quarryStart()
- end
- end
- if turtle.suckDown() == true then
- goodies = goodies+1
- checkChest()
- else
- if checkInv() < 1 then
- quarryStart()
- end
- end
- end
- end
- --*Checks the turtles current fuel level and attempts to refuel if low, returns to start if low fuel and no fuel on hand, if their is an enderchest in slot 15 will pull fuel from that
- function checkFuel()
- if turtle.getFuelLevel() < lowFuel then
- if enderFuel == true then
- turtle.turnRight()
- turtle.turnRight()
- turtle.select(15)
- turtle.place()
- turtle.suck()
- if turtle.refuel() ~= true then
- repeat
- turtle.drop()
- turtle.suck()
- if silentMode == false then
- t = {"Turtle is low on fuel, please refuel the fuel enderchest"}
- local msg = textutils.serialize(t)
- m.transmit(channel, channel, msg)
- end
- until turtle.refuel() == true
- end
- turtle.dig()
- turtle.select(16)
- turtle.turnRight()
- turtle.turnRight()
- else
- for i=1,16 do
- turtle.select(i)
- turtle.refuel()
- end
- end
- end
- return turtle.getFuelLevel()
- end
- --*Checks Turtle's inventory to verify it has space to proceed
- function checkInv()
- --Compares previous inv reading to blocks mined since last checkInv was executed
- if inv <= potentialInv then
- updatePos()
- if enderChest == false then
- inv = 0
- for i=1,14 do
- turtle.select(i)
- if turtle.getItemDetail() == nil then
- inv = inv + 1
- end
- end
- if inv < 2 then
- --Dumps items on the blacklist from inventory if enabled
- if dumpBlacklist == true then
- for i=1,14 do
- turtle.select(i)
- local data = turtle.getItemDetail()
- if data then
- if blacklistArray[data.name] then
- turtle.drop()
- end
- end
- end
- checkInv()
- end
- end
- turtle.select(16)
- potentialInv = 0
- else
- inv = 0
- for i=1,14 do
- turtle.select(i)
- if turtle.getItemDetail() == nil then
- inv = inv + 1
- end
- end
- if inv < 2 then
- --Dumps items on the blacklist from inventory if enabled
- if dumpBlacklist == true then
- for i=1,14 do
- turtle.select(i)
- local data = turtle.getItemDetail()
- if data then
- if blacklistArray[data.name] then
- turtle.drop()
- end
- end
- end
- end
- enderDump()
- checkInv()
- end
- turtle.select(16)
- potentialInv = 0
- end
- end
- return inv
- end
- --!The sweet sauce, Main function that executes logic to dig the current level the turtle is on
- function digLevel()
- if state ~= 1 then
- state = 1
- local h = fs.open(".lastState", "w")
- h.write("1")
- h.close()
- end
- curX = initX-1
- curZ = initZ-1
- while curX>0 or curZ>0 do
- if checkInv() > 1 and checkFuel() > lowFuel then
- if curZ > 0 then
- insp()
- if turtle.forward() == false then
- repeat
- turtle.attack()
- until turtle.forward() == true
- end
- curZ = curZ-1
- updatePos()
- end
- if curZ == 0 then
- if curX > 0 then
- if curX % 2 == 0 then
- turtle.turnLeft()
- insp2()
- if turtle.forward() == false then
- repeat
- turtle.attack()
- until turtle.forward() == true
- end
- turtle.turnLeft()
- else
- turtle.turnRight()
- insp2()
- turtle.forward()
- turtle.turnRight()
- end
- curX = curX-1
- curZ = initZ-1
- updatePos()
- else
- levelStart()
- end
- end
- else
- quarryStart()
- end
- end
- end
- --*Places the enderchest in slot 16 down empyties contents and picks it back up
- function enderDump()
- turtle.turnRight()
- turtle.turnRight()
- turtle.select(16)
- if turtle.place() == false then
- repeat
- turtle.dig()
- goodies = goodies+1
- until turtle.place() == true
- end
- for i=1,14 do
- turtle.select(i)
- if turtle.getItemDetail() then
- if turtle.drop() ~= true then
- print("Enderchest full returning to quarry start")
- turtle.select(16)
- turtle.dig()
- quarryStart()
- end
- end
- end
- turtle.select(16)
- turtle.dig()
- turtle.turnRight()
- turtle.turnRight()
- end
- --*Startup function that checks for previous in progress dig and runs first time variable values
- function initialize()
- sleep(2)
- --Checks if turtle has a wireless modem and wraps the peripheral
- if peripheral.getType("left") == "modem" then
- m = peripheral.wrap("left")
- elseif peripheral.getType("right") == "modem" then
- m = peripheral.wrap("right")
- else
- silentMode = true
- end
- if fs.exists(".lastPosition") then
- resume = true
- print("Resuming previous dig")
- if silentMode == false then
- t = {"Resuming previous dig"}
- local msg = textutils.serialize(t)
- m.transmit(channel, channel, msg)
- end
- else
- --Checks for GPS and set's current position based on GPS coordinates
- if gps.locate() and gpsDisable == false then
- x,y,z = gps.locate()
- if silentMode == false then
- gpsBroadcast = true
- else
- gpsBroadcast = false
- end
- end
- --Checks arguements provided on startup and sets initial X,Y,Z values
- if y and gpsDisable == false then
- if arg[1] and arg[2] then
- if arg[1] % 2 == 0 and arg[2] % 2 == 0 then
- initX = arg[1]
- initZ = arg[2]
- initY = y
- print("GPS Server detected")
- print("Currently Location is X:"..x.." Y:"..y.." Z:"..z)
- print("Mining "..initX.." X "..initZ.." area")
- else
- print("X and Z value's must be even")
- error()
- end
- else
- if arg[1] then
- if arg[1] % 2 == 0 then
- initX = arg[1]
- initZ = arg[1]
- initY = y
- print("GPS Server detected")
- print("Currently Location is X:"..x.." Y:"..y.." Z:"..z)
- print("Mining "..initX.." X "..initZ.." area")
- else
- print("X and Z value's must be even")
- error()
- end
- else
- initX = defaultX
- initZ = defaultZ
- initY = y
- print("GPS Server detected")
- print("Currently Location is X:"..x.." Y:"..y.." Z:"..z)
- print("Mining "..initX.." X "..initZ.." area")
- end
- end
- else
- if arg[1] and arg[2] and arg[3] then
- if arg[1] % 2 == 0 and arg[2] % 2 == 0 then
- initX = arg[1]
- initZ = arg[2]
- initY = arg[3]
- print("Currently on layer:"..initY)
- print("Mining "..initX.." X "..initZ.." area")
- else
- print("X and Z value's must be even")
- error()
- end
- else
- if arg[1] and arg[2] then
- if arg[1] % 2 == 0 then
- initX = arg[1]
- initZ = arg[1]
- initY = arg[2]
- print("Currently on layer:"..initY)
- print("Mining "..initX.." X "..initZ.." area")
- else
- print("X and Z value's must be even")
- error()
- end
- else
- if arg[1] then
- initX = defaultX
- initZ = defaultZ
- initY = arg[1]
- print("Currently on layer:"..initY)
- print("Mining "..initX.." X "..initZ.." area")
- else
- print("Error!")
- print("Could not determine current height.")
- print("Please specify height or deploy a GPS server.")
- error()
- end
- end
- end
- end
- print()
- --Checks for an enderchest in slot 15 to pull fuel from
- turtle.select(15)
- if turtle.getItemDetail() then
- if turtle.getItemDetail().name == "minecraft:ender_chest" or turtle.getItemDetail().name == "enderstorage:ender_storage" then
- enderFuel = true
- print("EnderChest detected in Fuel slot")
- print("Enabling EnderFuel")
- print()
- else
- enderFuel = false
- end
- end
- --Checks for an enderchest in slot 16 to dump items into
- turtle.select(16)
- if turtle.getItemDetail() then
- if turtle.getItemDetail().name == "minecraft:ender_chest" or turtle.getItemDetail().name == "enderstorage:ender_storage" then
- enderChest = true
- print("EnderChest detected in Chest slot")
- print("Enabling EnderDump")
- print()
- else
- enderChest = false
- end
- end
- --Declares starting value of rolling variable potential inventory
- potentialInv = 0
- inv = 0
- --Keep's track of how many items have been mined (Not unload tolerant)
- goodies = 0
- checkBlacklist()
- print("Variables Set")
- print("Starting new dig")
- if silentMode == false then
- t = {"Starting new dig"}
- local msg = textutils.serialize(t)
- m.transmit(channel, channel, msg)
- end
- sleep(5)
- updatePos()
- end
- end
- --*Inspects the block infront, above, and below
- function insp()
- local I, data = turtle.inspect()
- if I then
- repeat
- local I, data = turtle.inspect()
- if data.name ~= "minecraft:water" or data.name ~= "minecraft:lava" then
- if data.name == "minecraft:chest" then
- checkChest()
- else
- turtle.dig()
- goodies = goodies+1
- potentialInv = potentialInv + 1
- end
- end
- until I == false or data.name == "minecraft:water" or data.name == "minecraft:lava"
- end
- local I, data = turtle.inspectUp()
- if I then
- if data.name ~= "minecraft:water" or data.name ~= "minecraft:lava" then
- if data.name == "minecraft:chest" then
- checkChest()
- else
- if blacklistArray[data.name] then
- else
- turtle.digUp()
- goodies = goodies+1
- potentialInv = potentialInv + 1
- end
- end
- end
- end
- local I, data = turtle.inspectDown()
- if I then
- if data.name ~= "minecraft:water" or data.name ~= "minecraft:lava" then
- if data.name == "minecraft:chest" then
- checkChest()
- else
- if blacklistArray[data.name] then
- else
- turtle.digDown()
- goodies = goodies+1
- potentialInv = potentialInv + 1
- end
- end
- end
- end
- end
- --*Clone of Inspect but does not execute a sanity check incase of full inventory when turning corner before position is updated
- function insp2()
- local I, data = turtle.inspect()
- if I then
- repeat
- local I, data = turtle.inspect()
- if data.name ~= "minecraft:water" or data.name ~= "minecraft:lava" then
- if data.name == "minecraft:chest" then
- while turtle.suck() == true do
- turtle.suck()
- end
- turtle.dig()
- goodies = goodies+1
- potentialInv = potentialInv + 1
- else
- turtle.dig()
- goodies = goodies+1
- potentialInv = potentialInv + 1
- end
- end
- until I == false or data.name == "minecraft:water" or data.name == "minecraft:lava"
- end
- local I, data = turtle.inspectUp()
- if I then
- if data.name ~= "minecraft:water" or data.name ~= "minecraft:lava" then
- if data.name == "minecraft:chest" then
- while turtle.suckUp() == true do
- turtle.suckUp()
- end
- else
- if blacklistArray[data.name] then
- else
- turtle.digUp()
- goodies = goodies+1
- potentialInv = potentialInv + 1
- end
- end
- end
- end
- local I, data = turtle.inspectDown()
- if I then
- if data.name ~= "minecraft:water" or data.name ~= "minecraft:lava" then
- if data.name == "minecraft:chest" then
- while turtle.suckDown() == true do
- turtle.suckDown()
- end
- else
- if blacklistArray[data.name] then
- else
- turtle.digDown()
- goodies = goodies+1
- potentialInv = potentialInv + 1
- end
- end
- end
- end
- end
- --!Saves current location and returns turtle to the beginning of current level
- function levelStart()
- if state ~= 2 then
- state = 2
- local h = fs.open(".lastState", "w")
- h.write("2")
- h.close()
- end
- if curX % 2 == 0 then
- turtle.turnRight()
- savedZ = curZ
- else
- turtle.turnLeft()
- savedZ = initZ-curZ-1
- end
- savedX = initX-curX-1
- for i=1, savedX do
- if turtle.forward() == false then
- repeat
- turtle.attack()
- turtle.dig()
- goodies = goodies+1
- until turtle.forward() == true
- end
- savedX = savedX-1
- updatePos()
- end
- turtle.turnLeft()
- if curZ > 0 then
- for i=1, savedZ do
- if turtle.forward() == false then
- repeat
- turtle.attack()
- turtle.dig()
- goodies = goodies+1
- until turtle.forward() == true
- end
- savedZ = savedZ-1
- updatePos()
- end
- end
- turtle.turnRight()
- turtle.turnRight()
- end
- --_Returns turtle to the beginning of the quarry to empty inventory
- function quarryStart()
- if state ~= 3 then
- state = 3
- local h = fs.open(".lastState", "w")
- h.write("3")
- h.close()
- end
- print("Quarry Start")
- levelStart()
- end
- --_Returns turtle to the current digLevel before its inventory was filled
- function pathToCurrentLevel()
- if state ~= 4 then
- state = 4
- local h = fs.open(".lastState", "w")
- h.write("4")
- h.close()
- end
- end
- --_Returns turtle to the current progress it was at before its inventory was filled
- function pathToCurrentPosition()
- if state ~= 5 then
- state = 5
- local h = fs.open(".lastState", "w")
- h.write("5")
- h.close()
- end
- end
- --*Moves the turtle up to the next level to be mined, exits program at starting point
- function pathToNextLevel()
- --Checks to see if turtle is above starting point
- if curY + bedrock <= initY then
- --Checks to see if turtle can go up to next full level
- if curY + bedrock + 3 <= initY then
- for i=1, 3 do
- if turtle.up() == false then
- repeat
- turtle.digUp()
- goodies = goodies+1
- turtle.attackUp()
- until turtle.up() == true
- end
- curY = curY + 1
- end
- --Checks to see if turtle can go up a partial level
- elseif curY + bedrock + 2 <= initY then
- for i=1, 2 do
- if turtle.up() == false then
- repeat
- turtle.digUp()
- goodies = goodies+1
- turtle.attackUp()
- until turtle.up() == true
- end
- curY = curY + 1
- end
- --If turtle is 1 block below starting point goes to starting point
- elseif curY + bedrock + 1 == initY then
- if turtle.up() == false then
- repeat
- turtle.digUp()
- goodies = goodies+1
- turtle.attackUp()
- until turtle.up() == true
- end
- curY = curY + 1
- term.clear()
- term.setCursorPos(1,1)
- print("Mining Finished!")
- print()
- print("This turtle mined "..goodies.." items")
- error()
- else
- term.clear()
- term.setCursorPos(1,1)
- print("Mining Finished!")
- print()
- print("This turtle mined "..goodies.." items")
- error()
- end
- else
- term.clear()
- term.setCursorPos(1,1)
- print("Mining Finished!")
- print()
- print("This turtle mined "..goodies.." items")
- error()
- end
- end
- --*Moves the turtle down to the bottom level
- function pathToStart()
- if state ~= 0 then
- state = 0
- local h = fs.open(".lastState", "w")
- h.write("0")
- h.close()
- end
- curY = initY-bedrock
- for i=1, curY do
- if turtle.down() == false then
- repeat
- turtle.digDown()
- goodies = goodies+1
- turtle.attackDown()
- potentialInv = potentialInv + 1
- until turtle.down() == true
- end
- curY = curY - 1
- end
- updatePos()
- end
- --_Resumes mining if the turtle gets unloaded
- function resumePreviousDig()
- local file = fs.open(".initialPosition","r")
- local data = file.readAll()
- file.close()
- local ini = textutils.unserialize(data)
- initX = ini[1]
- initY = ini[2]
- initZ = ini[3]
- local file = fs.open(".lastPosition","r")
- local data = file.readAll()
- file.close()
- local pos = textutils.unserialize(data)
- curX = pos[1]
- curY = pos[2]
- curZ = pos[3]
- local file = fs.open(".lastState","r")
- local data = file.readAll()
- file.close()
- state = data
- end
- --!Updates the current position to a backup file incase of unload and broadcast's position if silentMode = false
- function updatePos()
- term.clear()
- term.setCursorPos(1,1)
- if gpsBroadcast == true then
- --Broadcast's current GPS coordinates
- x,y,z = gps.locate()
- t = {x,y,z,goodies}
- local msg = textutils.serialize(t)
- m.transmit(channel, channel, msg)
- print("Current Position is")
- print("X:"..x.." Y:"..y.." Z:"..z)
- print("Goodies Mined:"..goodies)
- elseif gpsBroadcast == false and silentMode == false then
- --Broadcast's current Y
- trueY = curY+bedrock
- m.transmit(channel, channel, trueY)
- print("Current Layer:"..trueY)
- print("X:"..x.." Y:"..y.." Z:"..z)
- print("Goodies Mined:"..goodies)
- else
- trueY = curY+bedrock
- print("Current Layer:"..trueY)
- print("Goodies Mined:"..goodies)
- end
- end
- --Program Started
- term.clear()
- term.setCursorPos(1,1)
- print(" ___ ___ ___")
- print(" / _ \\| _ \\| __|")
- print(" | (_) | /| _|")
- print(" \\___/|_|_\\|___| v0.01")
- print(" ___ _ _ _ ___ _____ __")
- print(" / _ \\| | | |/_\\ | _ \\ _ \\ \\ / /")
- print(" | (_) | |_| / _ \\| / /\\ V /")
- print(" \\__\\_\\\\___/_/ \\_\\_|_\\_|_\\ |_|")
- print()
- print(" REDUX! by. Soulgriever")
- print()
- initialize()
- if resume == true then
- resumePreviousDig()
- else
- pathToStart()
- while true do
- digLevel()
- pathToNextLevel()
- end
- end
Add Comment
Please, Sign In to add comment