Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local dropTable = setmetatable({
- ["minecraft:diamond_ore"] = "minecraft:diamond",
- ["minecraft:coal_ore"] = "minecraft:coal",
- ["minecraft:redstone_ore"] = "minecraft:redstone",
- ["minecraft:lapis_ore"] = "minecraft:lapis_lazuli",
- ["minecraft:emerald_ore"] = "minecraft:emerald",
- ["minecraft:nether_quartz_ore"] = "minecraft:quartz",
- ["minecraft:nether_gold_ore"] = "minecraft:gold_nugget",
- ["minecraft:stone"] = "minecraft:cobblestone"
- }, {__index = function(tab, block) return block end})
- local treasureTable = setmetatable({ --Descending priority order
- ["minecraft:diamond"] = 9,
- ["minecraft:emerald"] = 8,
- ["minecraft:gold_ingot"] = 7,
- ["minecraft:gold_ore"] = 6,
- ["minecraft:lapis_lazuli"] = 5,
- ["minecraft:iron_ore"] = 4,
- ["minecraft:redstone"] = 3,
- ["minecraft:coal"] = 2,
- ["minecraft:gold_nugget"] = 1
- }, {__index = function() return 0 end})
- local fuelRatio = 0.1
- local function refuel()
- if turtle.getFuelLevel() >= turtle.getFuelLimit() * fuelRatio then
- return true
- end
- local slotDetail = turtle.getItemDetail(16)
- if slotDetail == nil or slotDetail.name ~= "minecraft:coal" then
- return false
- end
- turtle.select(16)
- local neededCoal = math.ceil(((turtle.getFuelLimit() * fuelRatio) - turtle.getFuelLevel()) / 80)
- if neededCoal > slotDetail.count - 1 then
- turtle.refuel(slotDetail.count - 1)
- return false
- end
- turtle.refuel(neededCoal)
- return true
- end
- local function isSpaceFor(item)
- for slot=1, (item == "minecraft:coal" and 16 or 15) do
- local slotDetail = turtle.getItemDetail(slot)
- if slotDetail == nil or (slotDetail.name == item and turtle.getItemSpace(slot) > 0) then
- return true
- end
- end
- return false
- end
- local function trashExtra()
- local tSlotDetails = {}
- for priority=0, 9 do
- for slot=1, 15 do
- tSlotDetails[slot] = tSlotDetails[slot] or turtle.getItemDetail(slot, false)
- if tSlotDetails[slot] == nil then return slot end
- if treasureTable[dropTable[tSlotDetails[slot].name]] <= priority then
- turtle.select(slot)
- turtle.drop()
- return slot
- end
- end
- end
- end
- local function dig(dir)
- local success, blockDetails
- if (dir == "up") then
- if not turtle.detectUp() then return false end
- success, blockDetails = turtle.inspectUp()
- elseif (dir == "down") then
- if not turtle.detectDown() then return false end
- success, blockDetails = turtle.inspectDown()
- else
- if not turtle.detect() then return false end
- success, blockDetails = turtle.inspect()
- end
- local expectedItem = dropTable[blockDetails.name]
- if not isSpaceFor(expectedItem) and treasureTable[expectedItem] ~= 0 then
- trashExtra()
- end
- if expectedItem == "minecraft:coal" then
- turtle.select(16)
- else
- turtle.select(1)
- end
- --sleep(0.25)
- if dir == "up" then
- turtle.digUp()
- if turtle.detectUp() then return dig("up") end
- return true
- elseif dir == "down" then
- turtle.digDown()
- if turtle.detectDown() then return dig("down") end
- return true
- else
- turtle.dig()
- if turtle.detect() then return dig() end
- return true
- end
- end
- function investigateVein()
- local oreMap = setmetatable({},
- {
- __index = function(tab, xVal)
- if xVal == nil then
- error("Nil x value", 2)
- end
- tab[xVal] = setmetatable({},
- {
- __index = function(tab_2, yVal)
- if yVal == nil then
- error("Nil y value", 2)
- end
- tab_2[yVal] = {}
- return tab_2[yVal]
- end
- })
- return tab[xVal]
- end
- })
- local posX, posY, posZ = 0, 0, 0
- local facing = 0
- local function getFacingCoords(dir)
- if dir == 0 then
- return posX + 1, posY, posZ
- elseif dir == 1 then
- return posX, posY, posZ + 1
- elseif dir == 2 then
- return posX - 1, posY, posZ
- elseif dir == 3 then
- return posX, posY, posZ - 1
- end
- end
- local function recordBlockInfo(block, x, y, z)
- oreMap[x][y][z] = block
- return block
- end
- local function getBlockInfo(x, y, z)
- if rawget(oreMap, x) == nil or rawget(oreMap[x], y) == nil then return nil end
- return oreMap[x][y][z]
- end
- local function populateBlockInfo(dir)
- local x, y, z
- local success, blockInfo
- if dir == "up" or dir == "down" then
- x = posX
- y = posY + (dir == "up" and 1 or -1)
- z = posZ
- local currentInfo = getBlockInfo(x, y, z)
- if currentInfo ~= nil then return currentInfo end
- success, blockInfo = turtle[dir == "up" and "inspectUp" or "inspectDown"]()
- else
- x, y, z = getFacingCoords(facing)
- local currentInfo = getBlockInfo(x, y, z)
- if currentInfo ~= nil then return currentInfo end
- success, blockInfo = turtle.inspect()
- end
- if not success then
- blockInfo = {name = "minecraft:air"}
- end
- return recordBlockInfo(blockInfo, x, y, z)
- end
- local function checkBlockForDig(dir)
- local blockInfo = populateBlockInfo(dir)
- if treasureTable[dropTable[blockInfo.name]] > 0 then
- return dig(dir)
- end
- return false
- end
- local function turnRight()
- turtle.turnRight()
- facing = (facing + 1) % 4
- end
- local function turnLeft()
- turtle.turnLeft()
- facing = (facing - 1) % 4
- end
- local function forward()
- local result, err = turtle.forward()
- if result then
- if facing % 2 == 0 then
- posX = posX + (facing == 0 and 1 or -1)
- else
- posZ = posZ + (facing == 1 and 1 or -1)
- end
- return true
- else
- return false, err
- end
- end
- local function back()
- local result, err = turtle.back()
- if result then
- if facing % 2 == 0 then
- posX = posX - (facing == 0 and 1 or -1)
- else
- posZ = posZ - (facing == 1 and 1 or -1)
- end
- return true
- else
- return false, err
- end
- end
- local function up()
- local result, err = turtle.up()
- if result then
- posY = posY + 1
- return true
- else
- return false, err
- end
- end
- local function down()
- local result, err = turtle.down()
- if result then
- posY = posY - 1
- return true
- else
- return false, err
- end
- end
- local function numUnknownNeighbors(x, y, z)
- local count = 0
- count = count + (getBlockInfo(x+1, y, z) == nil and 1 or 0)
- count = count + (getBlockInfo(x-1, y, z) == nil and 1 or 0)
- count = count + (getBlockInfo(x, y+1, z) == nil and 1 or 0)
- count = count + (getBlockInfo(x, y-1, z) == nil and 1 or 0)
- count = count + (getBlockInfo(x, y, z+1) == nil and 1 or 0)
- count = count + (getBlockInfo(x, y, z-1) == nil and 1 or 0)
- return count
- end
- local function hasUnknownNeighbors(x, y, z)
- return getBlockInfo(x+1, y, z) == nil or getBlockInfo(x-1, y, z) == nil or getBlockInfo(x, y+1, z) == nil or getBlockInfo(x, y-1, z) == nil or getBlockInfo(x, y, z+1) == nil or getBlockInfo(x, y, z-1) == nil
- end
- local function turtleDist(x1, y1, z1, x2, y2, z2)
- return math.abs(x1 - x2) + math.abs(y1 - y2) + math.abs(z1 - z2)
- end
- local function getNextScanLocation()
- local closestX, closestY, closestZ, closestDist = math.huge, math.huge, math.huge, math.huge
- for x, xTab in pairs(oreMap) do
- for y, yTab in pairs(xTab) do
- for z, blockInfo in pairs(yTab) do
- if treasureTable[dropTable[blockInfo.name]]~=0 and hasUnknownNeighbors(x, y, z) then
- local dist = turtleDist(x, y, z, posX, posY, posZ)
- if closestX == math.huge or dist < closestDist then
- closestX = x
- closestY = y
- closestZ = z
- closestDist = dist
- if dist == 1 then
- return x, y, z
- end
- end
- end
- end
- end
- end
- if closestX == math.huge then return nil end
- return closestX, closestY, closestZ
- end
- local function turnToDir(dir)
- if dir == facing then return true end
- if dir == (facing + 1) % 4 then turnRight() return true end
- if dir == (facing - 1) % 4 then turnLeft() return true end
- turnRight()
- turnRight()
- return true
- end
- local function pathToPoint(x, y, z)
- local xDelta = x - posX
- local yDelta = y - posY
- local zDelta = z - posZ
- if xDelta ~= 0 or zDelta ~= 0 then
- if (zDelta == 0) or (facing == 0 and xDelta > 0) or (facing == 2 and xDelta < 0) or (facing == 1 and zDelta < 0) or (facing == 3 and zDelta > 0) then
- turnToDir(xDelta < 0 and 2 or 0)
- for i=1, math.abs(xDelta) do
- dig()
- forward()
- end
- if (zDelta ~= 0) then
- turnToDir(zDelta < 0 and 3 or 1)
- for i=1, math.abs(zDelta) do
- dig()
- forward()
- end
- end
- else
- turnToDir(zDelta < 0 and 3 or 1)
- for i=1, math.abs(zDelta) do
- dig()
- forward()
- end
- if (xDelta ~= 0) then
- turnToDir(xDelta < 0 and 2 or 0)
- for i=1, math.abs(xDelta) do
- dig()
- forward()
- end
- end
- end
- end
- if yDelta > 0 then
- for i=1, yDelta do
- dig("up")
- up()
- end
- elseif yDelta < 0 then
- for i=1, -yDelta do
- dig("down")
- down()
- end
- end
- end
- local function scan()
- local originalFacing = facing
- checkBlockForDig("up")
- checkBlockForDig("down")
- checkBlockForDig()
- if getBlockInfo(unpack({getFacingCoords((originalFacing + 1) % 4)})) ~= nil and getBlockInfo(getFacingCoords((facing + 2) % 4)) ~= nil then
- if getBlockInfo(unpack({getFacingCoords((originalFacing - 1) % 4)})) == nil then
- turnLeft()
- checkBlockForDig()
- end
- return
- else
- turnRight()
- checkBlockForDig()
- if getBlockInfo(unpack({getFacingCoords((originalFacing + 2) % 4)})) == nil or getBlockInfo(unpack({getFacingCoords((originalFacing + 3) % 4)})) == nil then
- turnRight()
- checkBlockForDig()
- end
- if getBlockInfo(unpack({getFacingCoords((originalFacing + 3) % 4)})) == nil then
- turnRight()
- checkBlockForDig()
- end
- end
- end
- --Main loop
- local nextX, nextY, nextZ = 0, 0, 0
- repeat
- refuel()
- pathToPoint(nextX, nextY, nextZ)
- scan()
- nextX, nextY, nextZ = getNextScanLocation()
- until nextX == nil
- pathToPoint(0,0,0)
- turnToDir(0)
- end
- local function probe(dir, forceDig)
- local success, blockDetails
- if dir=="up" then
- success, blockDetails = turtle.inspectUp()
- elseif dir=="down" then
- success, blockDetails = turtle.inspectDown()
- else
- success, blockDetails = turtle.inspect()
- end
- if success and treasureTable[dropTable[blockDetails.name]]~=0 then
- print("Found a", dropTable[blockDetails.name], "vein.")
- investigateVein()
- print("Finished mining vein.")
- elseif forceDig then
- dig(dir)
- end
- end
- local maxRuns = tonumber(...)
- for i=1, maxRuns do
- refuel()
- probe(nil, true)
- turtle.forward()
- probe("down")
- probe("up", true)
- turtle.turnLeft()
- probe()
- turtle.up()
- probe()
- probe("up")
- turtle.turnRight()
- turtle.turnRight()
- probe()
- turtle.down()
- probe()
- turtle.turnLeft()
- end
- turtle.turnLeft()
- turtle.turnLeft()
- for i=1, maxRuns do
- refuel()
- while turtle.detect() do
- turtle.dig()
- end
- turtle.forward()
- end
- turtle.turnRight()
- turtle.turnRight()
Add Comment
Please, Sign In to add comment