Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- location is a global table containing all the coordinates and facing direction of the turtle
- And here is the function to set the position of the turtle and another one to get it.
- ]]--
- location = {x = 0, y = 0, z = 0, f = 0}
- function setPosition (x, y, z, f)
- location.x = x
- location.y = y
- location.z = z
- location.f = f
- end
- function getPosition ()
- return { x = location.x,
- y = location.y,
- z = location.z,
- f = location.f, } -- return a copy of the location table.
- end
- --[[
- And a small function to print the position. For debug purposes
- ]]--
- function printPosition ()
- print ("Currrent turtle position:")
- print (" x = "..location.x)
- print (" y = "..location.y)
- print (" z = "..location.z)
- print (" f = "..location.f)
- end
- --[[
- A turning function
- ]]--
- function turn (direction)
- if direction == "left" then
- turtle.turnLeft()
- location.f = location.f - 1
- elseif direction == "right" then
- turtle.turnRight()
- location.f = location.f + 1
- elseif direction == "around" then
- turtle.turnLeft()
- turtle.turnLeft()
- location.f = location.f - 2
- else
- print ("No such direction: "..direction)
- return false
- end
- location.f = (location.f + 4) % 4 -- This is used to handle the f < 0 and f > 3 situations
- return true
- end
- --[[
- This one is used to turn the turtle to specified f direction.
- A little bit of pony magic is used to calculate how should it turn
- ]]--
- function turnTo (face)
- local diff = face - location.f
- if math.abs(diff) == 2 then --this is true if the difference between f and face is 2 or -2, so it should turn around
- return turn ("around")
- elseif math.fmod(diff + 4, 4) == 1 then --this is true if the difference between f and face is 1
- return turn ("right") --f = 0 and face = 3 is also satisfies the condition (-3 + 4 == 1)
- elseif math.fmod(diff - 4, 4) == -1 then --this is true if the difference between f and face is -1
- return turn ("left") --f = 3 and face = 1 is also satisfies the condition ( 3 - 4 == -1)
- end
- return false --returned if turtle is already faced the specified direction
- end
- --[[
- This function is used to return actual x and z shifts
- These shifts are the numbers which you should add to the coordinates when turtle moves forward.
- I use a table to decode it since it is more compact and easier to read than lots of conditions
- ]]--
- local tShifts = {
- [0] = { 1, 0},
- [1] = { 0, 1},
- [2] = {-1, 0},
- [3] = { 0, -1},
- }
- function fDirection ()
- return unpack (tShifts[location.f])
- end
- --[[
- This function is used to update the turtle location when it has moved
- ]]--
- function updateLocation (direction)
- if direction == "up" then
- location.y = location.y + 1
- elseif direction == "down" then
- location.y = location.y - 1
- elseif direction == "forward" then
- local xShift, zShift = fDirection ()
- location.x = location.x + xShift
- location.z = location.z + zShift
- elseif direction == "back" then
- local xShift, yShift = fDirection ()
- location.x = location.x - xShift
- location.z = location.z - zShift
- end
- end
- --This function tries to refuel the turtle to make it have an <amount> of fuel--
- function refuel (amount)
- if turtle.getFuelLevel () > amount then
- return true
- end
- for i=1,16 do
- if turtle.getItemCount (i) > 0 then
- turtle.select (i)
- while turtle.refuel (1) do
- if turtle.getFuelLevel () >= amount then
- turtle.select (1)
- return true
- end
- end
- end
- end
- turtle.select (1)
- return false
- end
- --[[
- This function checks if there are required amount of fuel,
- and if there's not, it tries to refuel it,
- if it fails, it hangs until refueling sucseeds.
- ]]--
- function checkFuel (amount)
- if turtle.getFuelLevel () > amount then
- return true
- else
- if not refuel (amount) then
- print "No fuel found! Please, add more fuel!"
- while not refuel (amount) do
- sleep (2)
- end
- end
- return true
- end
- end
- --[[
- Advanced movement function. You can pass a function to it which is executed each time turtle collects something.
- Again, I use a set of tables with all the movements and some other "directional" turtle actions
- These tables are global, so programs using this API can access them or even modify them to set, for example, they own forward function
- Warning! Moving functions should actually move the turtle and return true, or false if it can't move the turtle
- ]]--
- tMove = {
- forward = turtle.forward,
- up = turtle.up,
- down = turtle.down
- }
- tDetect = {
- forward = turtle.detect,
- up = turtle.detectUp,
- down = turtle.detectDown
- }
- tDig = {
- forward = turtle.dig,
- up = turtle.digUp,
- down = turtle.digDown
- }
- tAttack = {
- forward = turtle.attack,
- up = turtle.attackUp,
- down = turtle.attackDown
- }
- function move (direction, collectFunction)
- collectFunction = collectFunction or function () end --if collect function is not set, replace it with an empty function
- if not checkFuel (1) then
- return false
- end
- while not tMove[direction]() do
- if tDetect[direction]() then
- if tDig[direction]() then
- collectFunction ()
- else
- print "Can't pass the obstruction!"
- return false
- end
- elseif tAttack[direction]() then
- print "Aggressive liveforms detected! Combat mode engaged!"
- collectFunction ()
- end
- end
- updateLocation (direction)
- return true
- end
- --[[
- This one is used to move turtle to specified f direction OR up/down
- ]]--
- function moveEx (direction)
- if type(direction) == "number" then
- turnTo (direction)
- return move ("forward")
- else
- return move (direction)
- end
- end
- --[[
- Here is even more pony magic. You should pass to this function a table, which contains a bunch of small tables
- Those tables should contain two fields: <direction/function> and <count>
- For each of that small table turtle performs that function or moves to that direction <count> times
- It uses moveEx to move so you should specify the f direction if you want to move it
- ]]--
- function sequence (seq)
- for aNum, aTable in ipairs (seq) do
- action = aTable[1]
- count = aTable[2]
- if type(action) == "function" then
- for i = 1,count do
- action ()
- end
- else
- for i = 1,count do
- moveEx (action)
- end
- end
- end
- end
- --[[
- Small goto/turning function. It moves turtle in one axis.
- It uses the sequence function with only one element in sequence
- Conditions... Don't know how to make it better.
- Example: move.gotoOne ("x", 10) moves the turtle to x = 10
- ]]--
- function gotoOne (coordinate, value)
- if coordinate == "y" then
- local diff = value - location.y
- if diff > 0 then
- sequence { {"up", diff} }
- elseif diff < 0 then
- sequence { {"down", -diff} }
- end
- elseif coordinate == "x" then
- local diff = value - location.x
- if diff > 0 then
- sequence { {0, diff} }
- elseif diff < 0 then
- sequence { {2, -diff} }
- end
- elseif coordinate == "z" then
- local diff = value - location.z
- if diff > 0 then
- sequence { {1, diff} }
- elseif diff < 0 then
- sequence { {3, -diff} }
- end
- elseif coordinate == "f" then
- turnTo (value)
- end
- end
- --[[
- And finally the goto function! This is the REAL pony magic!
- It is kinda strange - it uses tables as arguments. For example,
- If you want to go to x, y, z = 10, 10, 10 call it this way:
- move.goto ({x = 10, y = 10, z = 10})
- But if you want turtle to go, for example, to y = 10 first,
- you can call it this way:
- move.goto ( {y = 10}, {x = 10, z = 10} )
- You can even pass a function as one of its arguments - and the turtle will execute it!
- ]]--
- function goto (...)
- local moveSequence = {}
- for number, argument in ipairs (arg) do --for each of the arguments passed to this function
- if type (argument) == "function" then --if it is a function
- table.insert (moveSequence, {argument, 1}) --add it to the sequence
- elseif type (argument) == "table" then --and if it is a table,
- local finalF = location.f --make a variable for the final f direction
- for key, value in pairs (argument) do --for each pair "key-value" in that table
- if key ~= "f" then --if it is not an f movement
- table.insert (moveSequence, --add to the sequence a table with a movement function
- { function() --and count = 1
- gotoOne (key, value)
- end, 1 })
- else
- finalF = value --if there is an f movement command
- end --store that f value in the variable
- end
- table.insert (moveSequence, --insert a turning command into the sequence
- { function()
- turnTo (finalF)
- end, 1 })
- end
- end
- sequence (moveSequence) --execute that sequence
- end
Advertisement
Add Comment
Please, Sign In to add comment