Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local headings = {"north", "east", "south", "west"}
- for i, value in ipairs(headings) do
- headings[value] = i
- end
- local function min(a, b)
- return a < b and a or b
- end
- local function max(a, b)
- return a > b and a or b
- end
- local function abs(x)
- return x < 0 and -x or x
- end;
- local function contains(table, item)
- for i, value in ipairs(table) do
- if value == item then
- return true
- end
- end
- return false
- end
- local function getVectorFromHeading(heading)
- if heading == "north" then return vector.new(0, 0, -1) end
- if heading == "east" then return vector.new(1, 0, 0) end
- if heading == "south" then return vector.new(0, 0, 1) end
- if heading == "west" then return vector.new(-1, 0, 0) end
- return vector.new(0, 0, 0)
- end
- local function getHeadingFromVector(offset, defaultHeading)
- if offset.x ~= 0 then
- return offset.x < 0 and "west" or "east"
- elseif offset.z ~= 0 then
- return offset.z < 0 and "north" or "south"
- end
- return defaultHeading or headings[1]
- end
- local function getStepWithBreak(step, breakBlocks)
- return function ()
- while not step() do
- if not breakBlocks() then
- return false
- end
- end
- return true
- end
- end
- local function moveTurtle(move, amount, step, moveOffset)
- local movedAmount = vector.new(0, 0, 0)
- for i = 1, amount do
- local moved = step()
- if not moved then break end
- movedAmount = movedAmount + moveOffset
- end
- move.currentPos = move.currentPos + movedAmount
- local moved = abs(movedAmount.x) + abs(movedAmount.y) + abs(movedAmount.z)
- return moved == amount, moved
- end
- local function turnTurtle(move, amount, turn, turnDirection)
- local turnedAmount = 0
- for i = 1, amount do
- local moved = turn()
- if not moved then break end
- turnedAmount = turnedAmount + turnDirection
- end
- local normalizedTurnedAmount = turnedAmount % 4
- local headingIndex = (headings[move.currentHeading] - 1 + normalizedTurnedAmount) % 4 + 1
- move.currentHeading = headings[headingIndex]
- return turnedAmount == amount, turnedAmount
- end
- local function turtleDig(detect, inspect, dig, blockBlacklist)
- while detect() do
- if blockBlacklist then
- local ok, block = inspect()
- if ok and contains(blockBlacklist, block.name) then
- return false
- end
- end
- if not dig() then
- return false
- end
- end
- return true
- end
- local function wrapNumber(x, maxValue)
- x = x % maxValue
- if x < 1 then
- x = x + maxValue
- end
- return x
- end
- local function getHeadingInDirection(currentHeading, direction)
- local index = wrapNumber(headings[currentHeading] + direction, 4)
- return headings[index]
- end
- local function getRequiredTurns(currentHeading, targetHeading, direction)
- local turns
- if direction < 0 then
- turns = wrapNumber(headings[currentHeading] - headings[targetHeading], 4)
- else
- turns = wrapNumber(headings[targetHeading] - headings[currentHeading], 4)
- end
- if turns == 4 then
- return 0
- end
- return turns
- end
- local function getFastestTurnDirection(currentHeading, targetHeading)
- local leftTurns = getRequiredTurns(currentHeading, targetHeading, -1)
- local rightTurns = getRequiredTurns(currentHeading, targetHeading, 1)
- return leftTurns < rightTurns and -1 or 1
- end
- local move = {
- headings = headings;
- getVectorFromHeading = getVectorFromHeading;
- getHeadingInDirection = getHeadingInDirection;
- getRequiredTurns = getRequiredTurns;
- getFastestTurnDirection = getFastestTurnDirection;
- currentPos = vector.new(0, 0, 0);
- currentHeading = headings[1];
- setCurrentPos = function (self, pos, heading)
- self.currentPos = pos
- self.currentHeading = heading
- end;
- forward = function (self, amount, tryBreakBlocks, blockBlacklist)
- local step = not tryBreakBlocks and turtle.forward or getStepWithBreak(turtle.forward, function ()
- return self:dig(blockBlacklist)
- end)
- return moveTurtle(self, amount or 1, step, getVectorFromHeading(self.currentHeading))
- end;
- back = function (self, amount, tryBreakBlocks, blockBlacklist)
- local step = not tryBreakBlocks and turtle.forward or getStepWithBreak(turtle.back, function ()
- self:turnLeft(2)
- local dug = self:dig(blockBlacklist)
- self:turnLeft(2)
- return dug
- end)
- return moveTurtle(self, amount or 1, step, getVectorFromHeading(self.currentHeading) * -1)
- end;
- up = function (self, amount, tryBreakBlocks, blockBlacklist)
- local step = not tryBreakBlocks and turtle.up or getStepWithBreak(turtle.up, function ()
- return self:digUp(blockBlacklist)
- end)
- return moveTurtle(self, amount or 1, step, vector.new(0, 1, 0))
- end;
- down = function (self, amount, tryBreakBlocks, blockBlacklist)
- local step = not tryBreakBlocks and turtle.down or getStepWithBreak(turtle.down, function ()
- return self:digDown(blockBlacklist)
- end)
- return moveTurtle(self, amount or 1, step, vector.new(0, -1, 0))
- end;
- turnLeft = function (self, amount)
- return turnTurtle(self, amount or 1, turtle.turnLeft, -1)
- end;
- turnRight = function (self, amount)
- return turnTurtle(self, amount or 1, turtle.turnRight, 1)
- end;
- turnTo = function (self, heading)
- local turnDirection = getFastestTurnDirection(self.currentHeading, heading)
- local turnAmount = getRequiredTurns(self.currentHeading, heading, turnDirection)
- if turnAmount > 0 then
- if turnDirection < 0 then
- return self:turnLeft(turnAmount)
- else
- return self:turnRight(turnAmount)
- end
- end
- return true, 0
- end;
- dig = function (self, blockBlacklist)
- return turtleDig(turtle.detect, turtle.inspect, turtle.dig, blockBlacklist)
- end;
- digUp = function (self, blockBlacklist)
- return turtleDig(turtle.detectUp, turtle.inspectUp, turtle.digUp, blockBlacklist)
- end;
- digDown = function (self, blockBlacklist)
- return turtleDig(turtle.detectDown, turtle.inspectDown, turtle.digDown, blockBlacklist)
- end;
- goTo = function (self, targetPos, breakBlocks, blockBlacklist)
- local movedAmount = 0
- local offset = targetPos - self.currentPos
- if offset.x ~= 0 then
- local heading = getHeadingFromVector(vector.new(offset.x, 0, 0), self.currentHeading)
- self:turnTo(heading)
- local moved, amount = self:forward(abs(offset.x), breakBlocks, blockBlacklist)
- movedAmount = movedAmount + amount
- if not moved then
- return false, movedAmount
- end
- end
- if offset.z ~= 0 then
- local heading = getHeadingFromVector(vector.new(0, 0, offset.z), self.currentHeading)
- self:turnTo(heading)
- local moved, amount = self:forward(abs(offset.z), breakBlocks, blockBlacklist)
- movedAmount = movedAmount + amount
- if not moved then
- return false, movedAmount
- end
- end
- if offset.y ~= 0 then
- if offset.y > 0 then
- local moved, amount = self:up(offset.y, breakBlocks, blockBlacklist)
- movedAmount = movedAmount + amount
- if not moved then
- return false, movedAmount
- end
- else
- local moved, amount = self:down(-offset.y, breakBlocks, blockBlacklist)
- movedAmount = movedAmount + amount
- if not moved then
- return false, movedAmount
- end
- end
- end
- return true, movedAmount
- end;
- }
- return move
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement