local numutil = require 'numutil' local function ensure_equipped(ptype, item) local cur = peripheral.getType"left" print(cur) if cur == ptype then return true end for i = 1,16 do local det = turtle.getItemDetail(i) if det and det.name == item then turtle.select(i) return turtle.equipLeft() end end return false, "couldn't find "..item end local function ensure_modem() return ensure_equipped("modem","computercraft:wireless_modem_normal") end local POS, FACING local function turtle_pos_init() assert(ensure_modem()) POS = vector.new(gps.locate()) while turtle.detect() do turtle.turnRight() end turtle.forward() local newpos = vector.new(gps.locate()) turtle.back() FACING = newpos - POS print("init with",POS,FACING) end local function moveby_y(delta) local fn = turtle.up if delta < 0 then fn = turtle.down delta = -delta end for i=1,delta do fn() end POS.y = POS.y + delta end local function rotatev(v,nq) -- rotates v by n quarters, clockwise (rightwards) nq = nq%4 if nq == 0 then return vector.new( v.x, v.y, v.z) elseif nq == 1 then return vector.new(-v.z, v.y, v.x) elseif nq == 2 then return vector.new(-v.x, v.y, -v.z) elseif nq == 3 then return vector.new( v.z, v.y, -v.x) end end local function turn_right() FACING = rotatev(FACING,1) turtle.turnRight() end local function turn_left() FACING = rotatev(FACING,-1) turtle.turnLeft() end local function turn_to_face(newfacing) if newfacing == FACING then return elseif newfacing == -FACING then turn_right() turn_right() elseif newfacing == rotatev(FACING,1) then turn_right() elseif newfacing == rotatev(FACING,-1) then turn_left() else error("invalid facing "..tostring(newfacing),2) end end local function move_linear(n) local dir = turtle.forward if n < 0 then dir = turtle.back end for i = 1,math.abs(n) do dir() end POS = POS + FACING*n end local function moveby_xz(dv) if FACING.x ~= 0 then move_linear(dv:dot(FACING)) if dv.z ~= 0 then turn_to_face(vector.new(0,0,numutil.sign(dv.z))) move_linear(dv:dot(FACING)) end elseif FACING.z ~= 0 then move_linear(dv:dot(FACING)) if dv.x ~= 0 then turn_to_face(vector.new(numutil.sign(dv.x),0,0)) move_linear(dv:dot(FACING)) end end end local function moveby(delta) moveby_y(delta.y) moveby_xz(delta) end local function moveto(target) print("moving to",target) moveby(target - POS) end local function do_column() if turtle.detectDown() then turtle.digDown() turtle.down() turtle.digDown() turtle.up() end end local function dump_and_refuel() print("dumping produce") os.sleep(1) local modem = peripheral.wrap"top" local self = modem.getNameLocal() print("i am",self) local ch = peripheral.find"sc-goodies:diamond_barrel" for i=1,16 do ch.pullItems(self, i) end while turtle.getFuelLevel() < 2000 do print("refuelling") for k,v in pairs(ch.list()) do if v.name == "minecraft:lava_bucket" then ch.pushItems(self, k, 1, 1) turtle.select(1) turtle.refuel() ch.pullItems(self, 1) goto nextfuel end goto nofuel end ::nextfuel:: end ::nofuel:: end local datum = vector.new(-18, 128, -1837) local function setup() turtle_pos_init() print("i am at",POS,"facing",FACING) moveto(datum) turn_to_face(vector.new(0,0,1)) dump_and_refuel() end local function loop() print("harvesting") repeat repeat do_column() move_linear(1) until POS.z == -1826 do_column() turn_right() move_linear(1) turn_right() repeat do_column() move_linear(1) until POS.z == datum.z do_column() turn_left() move_linear(1) turn_left() until POS.x <= -29 moveto(datum) turn_to_face(vector.new(0,0,1)) dump_and_refuel() os.sleep(120) end local function main() setup() while true do loop() end end while true do local ok, err = pcall(main) if not ok then print("err",err) end os.sleep(5) end