-- Do not lose state when reset (chunkloading etc) local state = (function () local path = ".state" local state_table = {} if fs.exists(path) then local f = fs.open(path, "r") state_table = textutils.unserialize(f.readAll()) f.close() end return setmetatable({}, { __index = state_table, __newindex = function(self, k, v) rawset(state_table, k, v) local f = fs.open(path, "w") f.write(textutils.serialize(state_table)) f.close() end, }) end)() -- Not sure whether this is a good idea --[[ if state.x == nil or state.y == nil or state.z == nil or state.o == nil then printError("[lib] position is not set") printError("[lib] defaulting to 0, 0, 0, +z") state.x = 0 state.y = 0 state.z = 0 state.o = 0 end ]] local function setPosition(x, y, z, direction) local o = ({ ["+z"] = 0, ["-x"] = 1, ["-z"] = 2, ["+x"] = 3, })[direction] state.x = x state.y = y state.z = z state.o = o end --[[ orientation: 0 = South (+z) 1 = West (-x) 2 = North (-z) 3 = East (+x) ]] local function move(raw_move, position_update) return function() success, err = raw_move() if not success then return false, err end position_update() return true end end local fwd = move(turtle.forward, function() if state.o == 1 or state.o == 3 then state.x = state.x + ((state.o == 1) and -1 or 1) elseif state.o == 0 or state.o == 2 then state.z = state.z + ((state.o == 2) and -1 or 1) end end) local back = move(turtle.back, function() if state.o == 1 or state.o == 3 then state.x = state.x + ((state.o == 1 and 1 or -1)) elseif state.o == 0 or state.o == 2 then state.z = state.z + ((state.o == 2) and 1 or -1) end end) local up = move(turtle.up, function() state.y = state.y + 1 end) local down = move(turtle.down, function() state.y = state.y - 1 end) local left = move(turtle.turnLeft, function() state.o = (state.o - 1) % 4 end) local right = move(turtle.turnRight, function() state.o = (state.o + 1) % 4 end) local function getOrientation() return ({"+z", "-x", "-z", "+x"})[1 + state.o] end local function rotateTowards(direction) local target_o = ({ ["+z"] = 0, ["-x"] = 1, ["-z"] = 2, ["+x"] = 3, })[direction] if not target_o then error(tostring(direction) .. " is not a valid direction.") end local delta_o = (target_o - state.o) % 4 if delta_o == 0 then -- orientation already correct elseif delta_o == 1 then right() elseif delta_o == 2 then right() right() elseif delta_o == 3 then left() end end return { state = state, fwd = fwd, back = back, up = up, down = down, left = left, right = right, setPosition = setPosition, getOrientation = getOrientation, rotateTowards = rotateTowards, }