Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- World eater turtle
- -- Mock APIs for editor support
- --[[
- local rednet = {
- open = function(_) end,
- broadcast = function(_) end,
- receive = function()
- return 0, ""
- end,
- }
- local fs = {
- open = function(_, _)
- return {
- close = function(_) end,
- readLine = function(_)
- return ""
- end,
- }
- end,
- }
- local turtle = {
- turnLeft = function() end,
- turnRight = function() end,
- dig = function() end,
- digDown = function() end,
- digUp = function() end,
- place = function() end,
- placeDown = function() end,
- placeUp = function() end,
- suck = function() end,
- suckDown = function() end,
- suckUp = function() end,
- refuel = function() end,
- getFuelLevel = function()
- return 0
- end,
- forward = function()
- return false
- end,
- back = function()
- return false
- end,
- down = function()
- return false
- end,
- up = function()
- return false
- end,
- }
- local gps = {
- locate = function(_)
- return 0, 0, 0
- end,
- }
- local os = {
- sleep = function(_) end,
- }
- local peripheral = {
- isPresent = function(_)
- return false
- end,
- }
- local parallel = {
- waitForAll = function(...)
- _ = ...
- return 1
- end,
- waitForAny = function(...)
- _ = ...
- end,
- }
- --]]
- local function refuel(y)
- if turtle.getFuelLevel() < 100 then
- turtle.select(1)
- if (y ~= nil) and (y > 10) then
- turtle.digDown()
- turtle.placeDown()
- turtle.suckDown()
- turtle.refuel()
- while turtle.getFuelLevel() < 100 do
- print("Waiting for fuel...")
- os.sleep(10)
- turtle.suckDown()
- turtle.refuel()
- end
- turtle.digDown()
- else
- turtle.placeUp()
- turtle.suckUp()
- turtle.refuel()
- while turtle.getFuelLevel() < 100 do
- print("Waiting for fuel...")
- os.sleep(10)
- turtle.suckUp()
- turtle.refuel()
- end
- turtle.digUp()
- end
- end
- end
- local function unload(y)
- if turtle.getItemCount(15) > 0 then
- if (y ~= nil) and (y > 10) then
- turtle.digDown()
- turtle.select(2)
- turtle.placeDown()
- for i = 3, 16 do
- if turtle.getItemCount(i) > 0 then
- turtle.select(i)
- turtle.dropDown()
- end
- end
- turtle.digDown()
- else
- turtle.digUp()
- turtle.select(2)
- turtle.placeUp()
- for i = 3, 16 do
- if turtle.getItemCount(i) > 0 then
- turtle.select(i)
- turtle.dropUp()
- end
- end
- turtle.digUp()
- end
- end
- end
- local function digToBedrock(y)
- turtle.dig()
- turtle.digDown()
- unload(y)
- refuel(y)
- while turtle.down() do
- if y ~= nil then
- y = y - 1
- end
- turtle.dig()
- turtle.digDown()
- unload(y)
- refuel(y)
- end
- return y
- end
- local function comeUp(y, y0)
- for _ = y, y0 - 1, 1 do
- turtle.up()
- refuel(y)
- end
- end
- local function forward()
- while not turtle.forward() do
- if not peripheral.isPresent("front") then
- turtle.dig()
- else
- local solution = parallel.waitForAny(function()
- local f = false
- while not f do
- f = turtle.forward()
- end
- end, function()
- os.sleep(math.random(100) * 0.05)
- turtle.down()
- end)
- if solution == 2 then
- local f = false
- while not f do
- os.sleep(0.2)
- f = turtle.up()
- end
- turtle.forward()
- end
- end
- end
- refuel(11)
- end
- local function back()
- while not turtle.back() do
- os.sleep(0.2)
- end
- end
- local function getOrientation(x, z)
- forward()
- local x1, _, z1 = gps.locate(1)
- back()
- if x1 > x then
- return "east"
- elseif x1 < x then
- return "west"
- elseif z1 > z then
- return "south"
- else
- return "north"
- end
- end
- local function turnTo(orientation, current_orientation)
- if orientation == "north" then
- if current_orientation == "east" then
- turtle.turnLeft()
- elseif current_orientation == "south" then
- turtle.turnLeft()
- turtle.turnLeft()
- elseif current_orientation == "west" then
- turtle.turnRight()
- end
- elseif orientation == "east" then
- if current_orientation == "south" then
- turtle.turnLeft()
- elseif current_orientation == "west" then
- turtle.turnLeft()
- turtle.turnLeft()
- elseif current_orientation == "north" then
- turtle.turnRight()
- end
- elseif orientation == "south" then
- if current_orientation == "west" then
- turtle.turnLeft()
- elseif current_orientation == "north" then
- turtle.turnLeft()
- turtle.turnLeft()
- elseif current_orientation == "east" then
- turtle.turnRight()
- end
- elseif orientation == "west" then
- if current_orientation == "north" then
- turtle.turnLeft()
- elseif current_orientation == "east" then
- turtle.turnLeft()
- turtle.turnLeft()
- elseif current_orientation == "south" then
- turtle.turnRight()
- end
- end
- end
- local function go_to(x, z, xt, zt, orientation)
- if x < xt then
- turnTo("east", orientation)
- orientation = "east"
- while x < xt do
- forward()
- x = x + 1
- end
- elseif x > xt then
- turnTo("west", orientation)
- orientation = "west"
- while x > xt do
- forward()
- x = x - 1
- end
- end
- if z < zt then
- turnTo("south", orientation)
- while z < zt do
- forward()
- z = z + 1
- end
- elseif z > zt then
- turnTo("north", orientation)
- while z > zt do
- forward()
- z = z - 1
- end
- end
- turnTo("east", orientation)
- end
- local SETTINGS_FILE_NAME = ".eater_settings"
- local TASK_FILE_NAME = ".eater_task"
- rednet.open("right")
- local x, y, z = gps.locate(1)
- local x0, y0, z0, master_id = nil, nil, nil, nil
- if fs.exists(SETTINGS_FILE_NAME) then
- local f = fs.open(SETTINGS_FILE_NAME, "r")
- x0 = tonumber(f.readLine())
- y0 = tonumber(f.readLine())
- z0 = tonumber(f.readLine())
- master_id = tonumber(f.readLine())
- f.close()
- else
- rednet.broadcast("eater_turtle search")
- while master_id == nil do
- local id, msg = rednet.receive()
- if msg:sub(1, #"eater_master zero") == "eater_master zero" then
- master_id = id
- x0, y0, z0 = msg:match("eater_master zero (-?%d+) (-?%d+) (-?%d+)")
- x0, y0, z0 = tonumber(x0), tonumber(y0), tonumber(z0)
- print("Master with id " .. master_id .. " found at " .. x0 .. " " .. y0 .. " " .. z0)
- else
- print("Received unknown message, ignoring")
- end
- end
- local f = fs.open(SETTINGS_FILE_NAME, "w")
- f.writeLine(x0)
- f.writeLine(y0)
- f.writeLine(z0)
- f.writeLine(master_id)
- f.close()
- end
- if (y == nil) or (y < y0) then
- y = digToBedrock(y)
- while y == nil do
- turtle.up()
- x, y, z = gps.locate(1)
- end
- comeUp(y, y0)
- elseif y > y0 then
- refuel(y)
- while y > y0 do
- turtle.digDown()
- turtle.down()
- y = y - 1
- end
- local orientation = getOrientation(x, z)
- turnTo(orientation, "east")
- elseif fs.exists(TASK_FILE_NAME) then
- local f = fs.open(TASK_FILE_NAME, "r")
- local xt, zt = tonumber(f.readLine()) + x0, tonumber(f.readLine()) + z0
- f.close()
- go_to(x, z, xt, zt, getOrientation(x, z))
- y = digToBedrock(y)
- comeUp(y, y0)
- end
- local done = false
- while not done do
- rednet.send(master_id, "eater_turtle ready")
- local xt, zt = nil, nil
- while (xt == nil) and not done do
- local id, m = rednet.receive()
- if id == master_id then
- if m:sub(1, #"eater_master done") == "eater_master done" then
- done = true
- else
- xt, zt = m:match("eater_master go (-?%d+) (-?%d+)")
- xt, zt = tonumber(xt), tonumber(zt)
- print("Received task: " .. xt .. " " .. zt)
- local f = fs.open(TASK_FILE_NAME, "w")
- f.writeLine(xt)
- f.writeLine(zt)
- f.close()
- end
- end
- end
- if not done then
- go_to(x, z, xt + x0, zt + z0, "east")
- x, z = xt + x0, zt + z0
- y = digToBedrock(y)
- comeUp(y, y0)
- end
- end
- print("Done")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement