local FUEL_EFFICIENCY = 3 -- How many moves can the turtle do with a second of fuel tl = {} local function getv(dir) if dir==0 then return {x=0,y=0,z=1} elseif dir==1 then return {x=1,y=0,z=0} elseif dir==2 then return {x=0,y=0,z=-1} elseif dir==3 then return {x=-1,y=0,z=0} end end local function turtle_can_go(nname) return nname == "air" or minetest.registered_nodes[nname].liquidtype ~= "none" end function tl.forward(turtle, cptr) local info = get_turtle_info(turtle) if info.fuel == 0 then cptr.X = 0 return end local spos = info.spos local dir = info.dir local npos = vector.add(spos, getv(dir)) if turtle_can_go(minetest.get_node(npos).name) then info.npos = npos info.moving = true info.fuel = info.fuel - 1 cptr.X = u16(-1) cptr.paused = true else cptr.X = 0 end end function tl.backward(turtle, cptr) local info = get_turtle_info(turtle) if info.fuel == 0 then cptr.X = 0 return end local spos = info.spos local dir = info.dir local npos = vector.add(spos, getv((dir+2)%4)) if turtle_can_go(minetest.get_node(npos).name) then info.npos = npos info.moving = true info.fuel = info.fuel - 1 cptr.X = u16(-1) cptr.paused = true else cptr.X = 0 end end function tl.up(turtle, cptr) local info = get_turtle_info(turtle) if info.fuel == 0 then cptr.X = 0 return end local spos = info.spos local npos = vector.add(spos, {x=0, y=1, z=0}) if turtle_can_go(minetest.get_node(npos).name) then info.npos = npos info.moving = true info.fuel = info.fuel - 1 cptr.X = u16(-1) cptr.paused = true else cptr.X = 0 end end function tl.down(turtle, cptr) local info = get_turtle_info(turtle) if info.fuel == 0 then cptr.X = 0 return end local spos = info.spos local npos = vector.add(spos, {x=0, y=-1, z=0}) if turtle_can_go(minetest.get_node(npos).name) then info.npos = npos info.moving = true info.fuel = info.fuel - 1 cptr.X = u16(-1) cptr.paused = true else cptr.X = 0 end end function tl.turnleft(turtle, cptr) local info = get_turtle_info(turtle) info.ndir = (info.dir+3)%4 info.rotate = math.pi/2 info.moving = true cptr.paused = true end function tl.turnright(turtle, cptr) local info = get_turtle_info(turtle) info.ndir = (info.dir+1)%4 info.rotate = -math.pi/2 info.moving = true cptr.paused = true end local function write_string_at(cptr, addr, str) for i=1, string.len(str) do cptr[u16(addr-1+i)] = string.byte(str, i) end cptr.X = string.len(str) end local function turtle_detect(turtle, cptr, dir) local info = get_turtle_info(turtle) local pos = vector.add(info.spos, dir) local name = minetest.get_node(pos).name write_string_at(cptr, cptr.X, name) end function tl.detect(turtle, cptr) local info = get_turtle_info(turtle) turtle_detect(turtle, cptr, getv(info.dir)) end function tl.detectup(turtle, cptr) turtle_detect(turtle, cptr, {x = 0, y = 1, z = 0}) end function tl.detectdown(turtle, cptr) turtle_detect(turtle, cptr, {x = 0, y = -1, z = 0}) end local function turtle_dig(turtle, cptr, dir) local info = get_turtle_info(turtle) local dpos = vector.add(info.spos, dir) local dnode = minetest.get_node(dpos) if turtle_can_go(dnode.name) or dnode.name == "ignore" then cptr.X = 0 return end local drops = minetest.get_node_drops(dnode.name, "default:pick_mese") local _, dropped_item for _, dropped_item in ipairs(drops) do local leftover = turtle_invs:add_item(turtle,dropped_item) minetest.add_item(info.spos,leftover) end minetest.remove_node(dpos) cptr.X = u16(-1) cptr.paused = true end function tl.dig(turtle, cptr) local info = get_turtle_info(turtle) turtle_dig(turtle, cptr, getv(info.dir)) end function tl.digup(turtle, cptr) turtle_dig(turtle, cptr, {x = 0, y = 1, z = 0}) end function tl.digdown(turtle, cptr) turtle_dig(turtle, cptr, {x = 0, y = -1, z = 0}) end local function turtle_place(turtle, cptr, dir, slot) local info = get_turtle_info(turtle) local ppos = vector.add(info.spos, dir) local dnode = minetest.get_node(ppos) if (not turtle_can_go(dnode.name)) or dnode.name == "ignore" then cptr.X = 0 return end local stack = turtle_invs:get_stack(turtle, slot) if stack:is_empty() or minetest.registered_nodes[stack:get_name()] == nil then cptr.X = 0 return end minetest.set_node(ppos, {name=stack:get_name()}) stack:take_item() turtle_invs:set_stack(turtle, slot, stack) cptr.X = u16(-1) cptr.paused = true end function tl.place(turtle, cptr, slot) local info = get_turtle_info(turtle) turtle_place(turtle, cptr, getv(info.dir), slot) end function tl.placeup(turtle, cptr, slot) turtle_place(turtle, cptr, {x = 0, y = 1, z = 0}, slot) end function tl.placedown(turtle, cptr, slot) turtle_place(turtle, cptr, {x = 0, y = -1, z = 0}, slot) end local function stack_set_count(stack, count) stack = stack:to_table() if stack==nil then return nil end stack.count=count return ItemStack(stack) end function tl.refuel(turtle, cptr, slot, nmax) local info = get_turtle_info(turtle) local stack = turtle_invs:get_stack(turtle, slot) local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = {stack}}) if fuel.time <= 0 then cptr.X = 0 return end local count = math.min(stack:get_count(), nmax) local fs = stack:to_table() fs.count = 1 local fstack = ItemStack(fs) local fuel, afterfuel fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = {fstack}}) stack:take_item(count) if afterfuel ~= nil then afterfuel = afterfuel.items[1] end if afterfuel ~= nil then afterfuel = stack_set_count(afterfuel, afterfuel:get_count()*count) end if afterfuel ~= nil then local leftover = stack:add_item(ItemStack(afterfuel)) turtle_invs:set_stack(turtle, slot, stack) local leftover2 = turtle_invs:add_item(turtle, leftover) minetest.add_item(info.spos,leftover2) else turtle_invs:set_stack(turtle, slot, stack) end info.fuel = info.fuel+FUEL_EFFICIENCY*count*fuel.time cptr.X = u16(FUEL_EFFICIENCY*count*fuel.time) end