Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- -------------------------------
- --
- -- -------------------------------
- local function showUsage()
- print("chunkDig5")
- print("slot1 : torch x 64")
- print("slot2 : chest x 64")
- print("slot3 : cobblestone x 32")
- print("slot4 : stone x 1")
- print("slot5 : gravel x 1")
- print("slot6 : dart x 1")
- end
- -- -------------------------------
- -- config
- -- -------------------------------
- local SLOT_TORCH = 1
- local SLOT_CHEST = 2
- local SLOT_COBBLESTONE = 3
- local SLOT_STONE = 4
- local SLOT_GRAVEL = 5
- local SLOT_DART = 6
- local SLOTS_FREE = { 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
- local SLOTS_USELESS_SAMPLE = { SLOT_STONE, SLOT_GRAVEL, SLOT_DART, SLOT_COBBLESTONE }
- local SLOTS_KEEP_ALL = { SLOT_TORCH, SLOT_CHEST }
- local SLOTS_KEEP_32 = { SLOT_COBBLESTONE }
- local SLOTS_KEEP_1 = { SLOT_STONE, SLOT_GRAVEL, SLOT_DART }
- local INITIAL_HEIGHT = 58
- local BOTTOM_HEIGHT = 5
- local LOW_FUEL_LEVEL = 300
- local SIZE_LEFT = 80
- local SIZE_FORWARD = 80
- -- -------------------------------
- -- utility
- -- -------------------------------
- -- ---------------
- -- Logger
- -- ---------------
- -- do logging?
- local DEBUG_LOG = false
- -- local log
- local LOCAL_ENABLED = true
- local LOCAL_LOG_FILE_NAME = "debug.log"
- -- remote log
- local REMOTE_ENABLED = false
- local REMOTE_ADDR = 20
- local REMOTE_MODEM_DIR = "right"
- local function debug(txt)
- if DEBUG_LOG then
- if LOCAL_ENABLED then
- local hFile
- if fs.exists(LOCAL_LOG_FILE_NAME) then
- hFile = fs.open(LOCAL_LOG_FILE_NAME, "a");
- else
- hFile = fs.open(LOCAL_LOG_FILE_NAME, "w");
- end
- hFile.writeLine(txt);
- hFile.close();
- end
- if REMOTE_ENABLED then
- rednet.open(REMOTE_MODEM_DIR)
- rednet.send(REMOTE_ADDR, txt)
- rednet.close()
- end
- end
- end
- -- ---------------
- -- (common) direction code
- -- ---------------
- local DIR_FORWARD = 1
- local DIR_RIGHT = 2
- local DIR_BACK = 3
- local DIR_LEFT = 4
- local DIR_NOT = 5
- -- ---------------
- -- (common) turn code
- -- ---------------
- local TURN_NOT = 1
- local TURN_LEFT = 2
- local TURN_RIGHT = 3
- local TURN_OPPOSIT = 4
- -- ---------------
- -- TargetFinder
- -- ---------------
- local TargetFinder = {
- iterator = function(width, depth)
- findTarget = function(scanX, scanZ, reverse, rangeWidth, rangeDepth)
- local TILE_PATTERN = {"*","b","r","l","f"}
- local SHAPE_DIRECTION = { DIR_NOT, DIR_FORWARD, DIR_LEFT,
- DIR_RIGHT, DIR_BACK }
- local idx = ( (scanZ%5) + (scanX%5)*3 )%5 + 1
- local dirChar = TILE_PATTERN[idx]
- if (not reverse and "b" == dirChar) or
- ( reverse and "f" == dirChar) then
- return false
- end
- local DIR_TO_CENTER = {{ dx = 0, dz = 0 }, -- *
- { dx = 0, dz = -1 }, -- b
- { dx = 1, dz = 0 }, -- r
- { dx = -1, dz = 0 }, -- l
- { dx = 0, dz = 1 }} -- f
- local DIR_TO_NAME = {
- [DIR_FORWARD] = "F",
- [DIR_RIGHT ] = "R",
- [DIR_BACK ] = "B",
- [DIR_LEFT ] = "L",
- [DIR_NOT ] = "*"}
- local isCenter = false
- local found = false
- local newX, newZ
- local shape = {}
- local shapeDbg = ""
- local centerX = scanX + DIR_TO_CENTER[idx].dx
- local centerZ = scanZ + DIR_TO_CENTER[idx].dz
- local function inRange(posX, posY, width, height)
- return 0 <= posX and posX < width and 0 <= posY and posY < height
- end
- if inRange(centerX, centerZ, rangeWidth, rangeDepth) then
- found = true
- isCenter = true
- newX = centerX
- newZ = centerZ
- else
- table.insert(shape, DIR_NOT)
- shapeDbg = shapeDbg .. "*"
- end
- local testX, testZ
- for i = 2, 5 do
- testX = centerX - DIR_TO_CENTER[i].dx
- testZ = centerZ - DIR_TO_CENTER[i].dz
- if inRange(testX, testZ, rangeWidth, rangeDepth) then
- if isCenter then
- table.insert(shape, SHAPE_DIRECTION[i])
- shapeDbg = shapeDbg .. DIR_TO_NAME[SHAPE_DIRECTION[i]]
- end
- if not found then
- newX = testX
- newZ = testZ
- end
- found = true
- end
- end
- if not found then
- return false
- end
- return true, newX, newZ, shape, shapeDbg
- end
- local xAxisIterator = function(width)
- local pos = 0
- local loopEnd = math.floor((width + 1) / 3)
- return function()
- local current = pos
- pos = pos + 1
- if loopEnd < current then
- return nil
- else
- return current * 3
- end
- end
- end
- local zAxisIterator = function(x, depth)
- local pos, step
- if 0 == x % 2 then
- pos, step = -1, 1
- else
- pos, step = depth, -1
- end
- return function()
- local current = pos
- pos = pos + step
- if current < -1 or depth < current then
- return nil
- else
- return current
- end
- end
- end
- local xIter = xAxisIterator(width)
- local zIter = nil
- local x
- local previousX
- local previousZ
- return function()
- while true do
- if nil == zIter then
- x = xIter()
- if nil == x then
- return nil
- end
- zIter = zAxisIterator(x, depth)
- end
- local z = zIter()
- if nil == z then
- zIter = nil
- else
- --return x, z
- local found, newX, newZ, shape, shapeDbg
- = findTarget(x, z, 0 == x%2, width, depth)
- if found and (previousX ~= newX or previousZ ~= newZ) then
- previousX = newX
- previousZ = newZ
- return newX, newZ, shape, shapeDbg
- end
- end
- end
- end
- end
- }
- -- ---------------
- -- Move/Dig Functions
- -- ---------------
- function surelyUp()
- while not turtle.up() do turtle.digUp() end
- end
- function surelyDown()
- while not turtle.down() do end
- end
- -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
- function surelyDigUp()
- while turtle.digUp() do
- os.sleep(0.4)
- end
- end
- -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
- function surelyDig()
- while turtle.dig() do end
- end
- -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
- function surelyFwd()
- for i=1,4 do
- local status, err = turtle.forward()
- if status then
- return true -- success!
- elseif err=="Out of fuel" then
- return status, err
- end
- surelyDig() -- face to a normal block or a sand(gravel) hill
- if turtle.detect() and not turtle.dig() then
- return false, "bedrock!"
- end
- if turtle.forward() then return true end -- success!
- if turtle.attack() then
- -- face to monster-mob
- while turtle.attack() do end
- else
- -- face to sand-blocks which is dropping long time
- os.sleep(5) -- probably, adjustment is required
- end
- end
- return turtle.forward()
- end
- -- ---------------
- -- MyTurtle
- -- ---------------
- local MyTurtle = {}
- MyTurtle.new = function(initialY)
- local obj = {}
- obj.turtleX = 0
- obj.turtleZ = 0
- obj.turtleY = initialY
- obj.turtleDir = DIR_FORWARD
- return setmetatable(obj, {__index = MyTurtle})
- end
- MyTurtle.turnTo = function(self, direction)
- local TURN_RULES = { -- dir_forward, dir_right, dir_back, dir_left
- [DIR_FORWARD] = { TURN_NOT , TURN_RIGHT , TURN_OPPOSIT, TURN_LEFT },
- [DIR_RIGHT ] = { TURN_LEFT , TURN_NOT , TURN_RIGHT , TURN_OPPOSIT },
- [DIR_BACK ] = { TURN_OPPOSIT, TURN_LEFT , TURN_NOT , TURN_RIGHT },
- [DIR_LEFT ] = { TURN_RIGHT , TURN_OPPOSIT, TURN_LEFT , TURN_NOT }}
- local turn = TURN_RULES[self.turtleDir][direction]
- if TURN_LEFT == turn then
- if not SIMULATION then
- turtle.turnLeft()
- end
- elseif TURN_RIGHT == turn then
- if not SIMULATION then
- turtle.turnRight()
- end
- elseif TURN_OPPOSIT == turn then
- if not SIMULATION then
- turtle.turnLeft()
- turtle.turnLeft()
- end
- end
- self.turtleDir = direction
- end
- MyTurtle.adjustX = function(self, aimX, withDigUp, beforeEvHandlers, afterEvHandlers)
- if self.turtleX < aimX and DIR_RIGHT ~= self.turtleDir then
- self:turnTo(DIR_RIGHT)
- elseif aimX < self.turtleX and DIR_LEFT ~= self.turtleDir then
- self:turnTo(DIR_LEFT)
- end
- local function sign(val)
- if val == 0 then
- return 0
- else
- return math.abs(val) / val
- end
- end
- while self.turtleX ~= aimX do
- if not SIMULATION then
- surelyFwd()
- if withDigUp then
- surelyDigUp()
- end
- end
- self.turtleX = self.turtleX + sign(aimX - self.turtleX)
- end
- end
- MyTurtle.adjustZ = function(self, aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
- if self.turtleZ < aimZ and DIR_FORWARD ~= self.turtleDir then
- self:turnTo(DIR_FORWARD)
- elseif aimZ < self.turtleZ and DIR_BACK ~= self.turtleDir then
- self:turnTo(DIR_BACK)
- end
- local function sign(val)
- if val == 0 then
- return 0
- else
- return math.abs(val) / val
- end
- end
- while self.turtleZ ~= aimZ do
- if not SIMULATION then
- surelyFwd()
- if withDigUp then
- surelyDigUp()
- end
- end
- self.turtleZ = self.turtleZ + sign(aimZ - self.turtleZ)
- end
- end
- MyTurtle.moveTo = function(self, aimX, aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
- self:adjustZ(aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
- self:adjustX(aimX, withDigUp, beforeEvHandlers, afterEvHandlers)
- end
- MyTurtle.backTo = function(self, aimX, aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
- self:adjustX(aimX, withDigUp, beforeEvHandlers, afterEvHandlers)
- self:adjustZ(aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
- end
- -- ---------------
- -- Revolving digging
- -- ---------------
- local function verticalMiningAction(_myT, _shape, _negativeSampleSlots, _digAny)
- local turnToNearestEdge = function (myT, shape)
- local TURN_COSTS = { [TURN_NOT] = 0, [TURN_LEFT] = 1,
- [TURN_RIGHT] = 2, [TURN_OPPOSIT] = 3 }
- local TURN_RULES = { -- dir_forward, dir_right, dir_back, dir_left
- [DIR_FORWARD] = { TURN_NOT , TURN_RIGHT , TURN_OPPOSIT, TURN_LEFT },
- [DIR_RIGHT ] = { TURN_LEFT , TURN_NOT , TURN_RIGHT , TURN_OPPOSIT },
- [DIR_BACK ] = { TURN_OPPOSIT, TURN_LEFT , TURN_NOT , TURN_RIGHT },
- [DIR_LEFT ] = { TURN_RIGHT , TURN_OPPOSIT, TURN_LEFT , TURN_NOT }}
- local OPPOSIT_DIR = {DIR_BACK, DIR_LEFT, DIR_FORWARD, DIR_LEFT}
- local turnMinCost = 99
- local smallestTurnDir = DIR_NOT
- local turnTmp, costTmp
- for _, dir in ipairs(shape) do
- turnTmp = TURN_RULES[myT.turtleDir][dir]
- costTmp = TURN_COSTS[turnTmp]
- if costTmp < turnMinCost then
- turnMinCost = costTmp
- smallestTurnDir = dir
- end
- end
- debug(" [dir] current, smallest = " .. tostring(myT.turtleDir) .. ", " .. tostring(smallestTurnDir))
- myT:turnTo(smallestTurnDir)
- end
- local getTurnFuncName = function(myT, shape)
- local TURN_RELATIVE = { -- turn_left, turn_right
- [DIR_FORWARD] = { [TURN_LEFT] = DIR_LEFT , [TURN_RIGHT] = DIR_RIGHT },
- [DIR_RIGHT ] = { [TURN_LEFT] = DIR_FORWARD, [TURN_RIGHT] = DIR_BACK },
- [DIR_BACK ] = { [TURN_LEFT] = DIR_RIGHT , [TURN_RIGHT] = DIR_LEFT },
- [DIR_LEFT ] = { [TURN_LEFT] = DIR_BACK , [TURN_RIGHT] = DIR_FORWARD }}
- local dirWhenTurnLeft = TURN_RELATIVE[myT.turtleDir][TURN_LEFT ]
- local dirWhenTurnRight = TURN_RELATIVE[myT.turtleDir][TURN_RIGHT]
- for _, dir in ipairs(shape) do
- if dir == dirWhenTurnLeft then
- return TURN_LEFT
- elseif dir == dirWhenTurnRight then
- return TURN_RIGHT
- end
- end
- end
- local digValuableBlockOnly = function(negativeSampleSlots)
- local TURN_RELATIVE = { -- turn_left, turn_right
- [DIR_FORWARD] = { [TURN_LEFT] = DIR_LEFT , [TURN_RIGHT] = DIR_RIGHT },
- [DIR_RIGHT ] = { [TURN_LEFT] = DIR_FORWARD, [TURN_RIGHT] = DIR_BACK },
- [DIR_BACK ] = { [TURN_LEFT] = DIR_RIGHT , [TURN_RIGHT] = DIR_LEFT },
- [DIR_LEFT ] = { [TURN_LEFT] = DIR_BACK , [TURN_RIGHT] = DIR_FORWARD }}
- local selSlot = 16
- local checkedSlot = -1
- for _, slot in ipairs(negativeSampleSlots) do
- if selSlot == slot then
- if turtle.compare() then
- return
- end
- checkedSlot = slot
- break
- end
- end
- for _, slot in ipairs(negativeSampleSlots) do
- if checkedSlot ~= slot then
- turtle.select(slot)
- if turtle.compare() then
- return
- end
- end
- end
- turtle.dig()
- return true
- end
- local myT = _myT
- local shape = _shape
- local negativeSampleSlots = _negativeSampleSlots
- local digAny = _digAny
- local firstFlg = true
- local turnLR
- return function()
- local TURN_RELATIVE = { -- turn_left, turn_right
- [DIR_FORWARD] = { [TURN_LEFT] = DIR_LEFT , [TURN_RIGHT] = DIR_RIGHT },
- [DIR_RIGHT ] = { [TURN_LEFT] = DIR_FORWARD, [TURN_RIGHT] = DIR_BACK },
- [DIR_BACK ] = { [TURN_LEFT] = DIR_RIGHT , [TURN_RIGHT] = DIR_LEFT },
- [DIR_LEFT ] = { [TURN_LEFT] = DIR_BACK , [TURN_RIGHT] = DIR_FORWARD }}
- if firstFlg then
- firstFlg = not firstFlg
- if 2 == #shape or 3 == #shape then
- turnToNearestEdge(myT, shape)
- turnLR = getTurnFuncName(myT, shape)
- else
- turnLR = TURN_RIGHT
- end
- end
- if 1 < #shape then
- for i = 1, #shape do
- if not SIMULATION then
- if digAny then
- surelyDig()
- else
- dug = digValuableBlockOnly(negativeSampleSlots)
- end
- end
- if i < #shape then
- myT:turnTo(TURN_RELATIVE[myT.turtleDir][turnLR])
- end
- end
- if 2 == #shape or 3 == #shape then
- if TURN_LEFT == turnLR then
- turnLR = TURN_RIGHT
- else
- turnLR = TURN_LEFT
- end
- end
- end
- end
- end
- -- ---------------
- -- eject worthless
- -- ---------------
- local function dropDownUselessBlocks()
- local cnt
- for _, v in ipairs(SLOTS_KEEP_1) do
- cnt = turtle.getItemCount(v)
- if 1 < cnt then
- turtle.select(v)
- turtle.dropDown(cnt - 1)
- end
- end
- for _, v in ipairs(SLOTS_KEEP_32) do
- cnt = turtle.getItemCount(v)
- if 32 < cnt then
- turtle.select(v)
- turtle.dropDown(cnt - 32)
- end
- end
- for _, v in ipairs(SLOTS_FREE) do
- cnt = turtle.getItemCount(v)
- if 0 < cnt then
- turtle.select(v)
- for _, w in ipairs(SLOTS_USELESS_SAMPLE) do
- if turtle.compareTo(w) then
- turtle.dropDown()
- break
- end
- end
- end
- end
- end
- -- ---------------
- -- drop all
- -- ---------------
- local function dropUpAll()
- for _, v in ipairs(SLOTS_FREE) do
- if 0 < turtle.getItemCount(v) then
- turtle.select(v)
- turtle.dropUp()
- end
- end
- end
- -- ---------------
- -- suck all
- -- ---------------
- local function suckUpAll()
- local MSG_NO_SPACE = "No space for items"
- local MSG_NO_ITEMS = "No items to take"
- turtle.select(1)
- while true do
- local rslt, msg = turtle.suckUp()
- if false == rslt then
- if msg == MSG_NO_SPACE then
- dropUpAll()
- break
- elseif msg == MSG_NO_ITEMS then
- turtle.digUp()
- surelyUp()
- turtle.select(SLOT_TORCH)
- turtle.placeUp()
- surelyDown()
- break
- else
- break
- end
- end
- end
- end
- -- ---------------
- -- refuelPrompt
- -- ---------------
- function refuelPrompt(moveFunc)
- local firstTime = true;
- while true do
- local rslt, msg;
- if nil ~= moveFunc then
- rslt, msg = moveFunc();
- else
- if firstTime then
- firstTime = false;
- rslt = false;
- msg = "Out of fuel";
- else
- return true;
- end
- end
- if not rslt and msg == "Out of fuel" then
- print("Out of fuel. please select [r]efuel or [q]uit.");
- print("(r/q)");
- local ch = read();
- if "q" == ch then
- print("Are you sure you want to stop the script?");
- print("(y/n)");
- ch = read();
- if "y" == ch then
- error("out of fuel.");
- end
- elseif "r" == ch then
- local selSlot = 1;
- while true do
- print("Please type current selected slot number.");
- ch = read();
- local num = tonumber(ch);
- if nil ~= num and 1 <= num and num <= 16 then
- selSlot = num;
- break;
- else
- print("Wrong input. Please retry.");
- end
- end
- while true do
- print("please set fuel item and type slot number.");
- print("When you finish refueling, Please type q.");
- print("FuelLevel = " .. turtle.getFuelLevel());
- ch = read();
- local num = tonumber(ch);
- if nil ~= num and 1 <= num and num <= 16 then
- turtle.select(num);
- local fRslt, fMsg = turtle.refuel();
- if not fRslt then
- print(fMsg);
- end
- elseif "q" == ch then
- turtle.select(selSlot);
- break;
- else
- print("Wrong input. Please retry.");
- end
- end
- end
- else
- return rslt, msg;
- end
- end
- end
- -- -------------------------------
- -- main
- -- -------------------------------
- debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
- debug("@@ chunkDig5.lua")
- debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
- local initY = INITIAL_HEIGHT
- local myT = MyTurtle.new(initY)
- local zFirst = false
- for newX, newZ, shape, shapeDbg in TargetFinder.iterator(SIZE_LEFT, SIZE_FORWARD) do
- debug("===============================")
- debug("== newX, newZ, shapeDbg, fuelLv = " .. tostring(newX) .. ", " .. tostring(newZ)
- .. ", " .. shapeDbg .. ", " .. tostring(turtle.getFuelLevel()))
- debug("===============================")
- if zFirst then
- myT:moveTo(newX, newZ, true)
- else
- myT:backTo(newX, newZ, true)
- end
- zFirst = not zFirst
- surelyUp()
- surelyUp()
- surelyUp()
- turtle.select(SLOT_COBBLESTONE)
- for i = 1, 4 do
- surelyDig()
- turtle.place()
- turtle.turnLeft()
- end
- surelyDown()
- local miningFunc = verticalMiningAction(myT, shape, nil, true)
- miningFunc()
- surelyDown()
- miningFunc()
- surelyDown()
- miningFunc()
- turtle.select(1)
- surelyUp()
- surelyUp()
- surelyUp()
- surelyDigUp()
- turtle.select(SLOT_COBBLESTONE)
- turtle.placeUp()
- surelyDown()
- surelyDown()
- while true do
- if turtle.getItemCount(SLOT_CHEST) <= 2 then
- print("************************")
- print("** chest required!!")
- print("************************")
- refuelPrompt()
- else
- break
- end
- end
- while true do
- if turtle.getItemCount(SLOT_TORCH) <= 2 then
- print("************************")
- print("** torch required!!")
- print("************************")
- refuelPrompt()
- else
- break
- end
- end
- turtle.select(SLOT_CHEST)
- turtle.placeUp()
- dropDownUselessBlocks()
- dropUpAll()
- surelyDown()
- turtle.select(1)
- miningFunc = verticalMiningAction(myT, shape, SLOTS_USELESS_SAMPLE, false)
- for i = initY, BOTTOM_HEIGHT+1, -1 do
- turtle.digDown()
- turtle.down()
- miningFunc()
- if i == initY then
- turtle.select(SLOT_COBBLESTONE)
- for j = 1, 4 do
- turtle.place()
- turtle.turnRight()
- end
- turtle.select(1)
- elseif i == initY - 1 then
- turtle.select(SLOT_CHEST)
- turtle.placeUp()
- turtle.select(1)
- end
- end
- for i = BOTTOM_HEIGHT, initY-1, 1 do
- surelyUp()
- end
- surelyUp()
- suckUpAll()
- surelyDown()
- turtle.digDown()
- turtle.select(SLOT_COBBLESTONE)
- turtle.placeDown()
- if turtle.getFuelLevel() <= LOW_FUEL_LEVEL then
- refuelPrompt()
- end
- turtle.select(1)
- end
- dropDownUselessBlocks()
- if zFirst then
- myT:moveTo(0, 0, false)
- else
- myT:backTo(0, 0, false)
- end
- myT:turnTo(DIR_FORWARD)
- debug("chunkDig5 was completed.")
- print("chunkDig5 was completed.")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement