diff --git a/turtle/Wood.lua b/turtle/Wood.lua new file mode 100644 index 0000000..c92337a --- /dev/null +++ b/turtle/Wood.lua @@ -0,0 +1,387 @@ +Wood = {isHome = false} + +function Wood:readConfig(path) + -- reading configFile into a table + if (path == nil) then + term.write("init must have a path for the config file as argument") + return -1 + end + if (type(path) ~= "string") then + term.write("invalid argument") + return -1 + end + if (not fs.exists(path)) then + term.write("could not find config file \n please make sure it exists and the path is correct") + return -1 + end + local file = fs.open(path, "r") + local config = {} + while true do + local line = file.readLine() + if not line then + break + end + local numLine = tonumber(line) + config[#config+1] = numLine + end + file.close() + + --ToDo: implement a sanity check for the config file + + self.treePos = {config[1] + config[5], config[2] + config[6], config[3] + config [7], config[8]} + self.homePos = {config[1], config[2], config[3], config[4]} +end + +function Wood:new(t) + t = t or {} + setmetatable(t, self) + self.__index = self + return t +end + +function Wood:autoHome() + self.dir = getDir() + self.x, self.y, self.z = gps.locate() + if (self.x == self.homePos[1] and self.y == self.homePos[2] and self.z == self.homePos[3] and self.dir == self.homePos[4]) then + self.isHome = true + self:log("turtle is already at home position") + return true + else + if (self:isOnTree()) then + self.isBroken = true + self:log("broken tree detected") + end + self:log("going to home position") + self:moveTo("home") + + + end +end + +function Wood:log(message) + if self.verbose == true then + print(message) + end +end + +function Wood:isOnTree() + return false +end + +function Wood:offset(position, dir, offset) + self:assertPositionFormat(position) + assert(type(dir) == "number", "dir must be a number") + assert(type(offset) == "number", "offset must be a number") + local newPosition = self:copyPositionTable(position) + dir = dir % 4 + if (dir == 0) then newPosition[1] = newPosition[1] - offset + elseif (dir == 1) then newPosition[3] = newPosition[3] - offset + elseif (dir == 2) then newPosition[1] = newPosition[1] + offset + else newPosition[3] = newPosition[3] + offset + end + return newPosition +end + +function Wood:copyPositionTable(position) + self:assertPositionFormat(position) + local positionClone = {} + for i = 1, 4 do + positionClone[i] = position[i] + end + return positionClone +end + +function Wood:assertPositionFormat(position) + assert(type(position) == "table", "the target is not a table") + assert(type(position[1]) == "number" and type(position[2]) == "number" and type(position[3]) == "number", "the table doesn't contain the position") + assert(type(position[4]) == "number", "direction is missing") +end + +function Wood:resolveTarget(target) + if target == "home" then + target = self.homePos + elseif target == "tree" then + target = self.treePos + elseif target == "sapling" then + target = self.treePos + target = self:offset(target, target[4], 1) + target[2] = target[2] + 1 + elseif target == "saplingChest" then + target = self.homePos + target = self:offset(target, target[4] - 1, 1) + elseif target == "coalChest" then + target = self.homePos + target = self:offset(target, target[4] -1, 2) + elseif target == "outputChest" then + target = self.homePos + target = self:offset(target, target[4] -1, -1) + end + + self:assertPositionFormat(target) + self:log("target resolved") + return target +end + +function Wood:moveTo(target) + target = self:resolveTarget(target) + self:log("moving to target") + + moveTo(target[1], target[2], target[3], target[4], self.dir) + + self.x, self.y, self.z, self.dir = target[1], target[2], target[3], target[4] + + self:log("target reached") + +end + +function Wood:hoverTo(target) + target = self:resolveTarget(target) + self:log("hovering to target") + + hoverTo(target[1], target[2], target[3], target[4], self.dir) + self.x, self.y, self.z, self.dir = target[1], target[2], target[3], target[4] + + self:log("target reached") +end + +function Wood:isPos(position) + position = self:resolveTarget(position) + return self.x == position[1] and self.y == position[2] and self.z == position[3] and self.dir == position[4] +end + +function Wood:checkTree(goBack) + if (goBack == nil) then goBack = true end + if(goBack == true) then + goBack = {self.x, self.y, self.z, self.dir} + end + + self:log("moving to tree") + self:moveTo("tree") + + self:log("inspecting tree...") + local bd, data = turtle.inspect() + local result + if (bd == false) then result = "nothing" + elseif (data.tags["minecraft:saplings"] == true) then result = "sapling" + elseif (data.tags["minecraft:logs"]) then result = "tree" + else result = "other" end + + self:log(result) + + if (goBack ~= false) then + self:log("moving to goBack") + self:moveTo(goBack) + end + + self:log("checkTree complete") + self.treeState = result + return result +end + +function Wood:cutTree(goBack) + if (goBack == nil) then goBack = true end + if(goBack == true) then + goBack = {self.x, self.y, self.z, self.dir} + end + + self:moveTo("tree") + + self:log("cutting tree...") + cut4() + self:log("successful") + + if (goBack ~= false) then + self:log("moving to goBack") + self:moveTo(goBack) + end + +end + +function Wood:plantTree(goBack) + if (goBack == nil) then goBack = true end + if(goBack == true) then + goBack = {self.x, self.y, self.z, self.dir} + end + + self:clearInv("saplingChest") + turtle.select(1) + turtle.suckDown(4) + + self:moveTo("sapling") + plant4(1) + + if (goBack ~= false) then + self:log("moving to goBack") + self:hoverTo(goBack) + end +end + +function Wood:sort(goBack) + if (goBack == nil) then goBack = true end + if(goBack == true) then + goBack = {self.x, self.y, self.z, self.dir} + end + + self:moveTo("home") + local hasMore = self:suckAllDown() + self:clearInv(goBack) + +end + +function Wood:suckAllDown() + for i = 1, 16 do + turtle.select(i) + if(turtle.getItemCount() == 0) then + if(turtle.suckDown() == false) then + return true + end + end + end + return false +end + +function Wood:clearInv(goBack) + if (goBack == nil) then goBack = true end + if(goBack == true) then + goBack = {self.x, self.y, self.z, self.dir} + end + if (self:isInInv("sapling", true)) then + self:moveTo("saplingChest") + self:dropItemsDown("sapling", false) + end + if (self:isInInv("coal", false)) then + self:moveTo("coalChest") + self:dropItemsDown("coal", false) + end + if (self:isInvEmpty(true) == false) then + self:moveTo("outputChest") + self:dropItemsDown("any", false) + end + + if (goBack ~= false) then + self:log("moving to goBack") + self:moveTo(goBack) + end +end + +function Wood:isInInv(item, update) + assert(type(item) == "string", "item must be a string") + self:assertInvUpdate(update) + + local tag = self:resolveTag(item) + if (tag == "") then + for i = 1, 16 do + if self:checkItemName(item, i) == true then return true end + end + else + for i = 1, 16 do + if self:checkItemTag(tag, i) == true then return true end + end + end + return false +end + +function Wood:dropItemsDown(item, update) + assert(type(item) == "string", "item must be a string") + self:assertInvUpdate(update) + + local tag = self:resolveTag(item) + + if(tag == "") then + for i = 1, 16 do + if self:checkItemName(item, i) == true then + turtle.select(i) + turtle.dropDown() + end + end + else + for i = 1, 16 do + if self:checkItemTag(tag, i) == true then + turtle.select(i) + turtle.dropDown() + end + end + end + +end + +function Wood:resolveTag(item) + local tag = "" + if (item == "sapling") then + tag = "minecraft:saplings" + elseif (item == "log" or item == "wood") then + tag = "minecraft:logs" + elseif (item == "coal") then + tag = "minecraft:coals" + end + return tag +end + +function Wood:checkItemTag(tag, slot) + assert(type(tag) == "string", "tag must be a string") + assert(type(slot) == "number" and slot > 0 and slot <= 16, "slot must be between 1 and 16") + if self.inv[slot] == nil then + self:log("self.inv is empty at slot "..tostring(slot)) + return false + end + if self.inv[slot].tags == nil then + self:log("no tags found") + return false + end + if self.inv[slot].tags[tag] == true then + return true + else + return false + end +end + +function Wood:checkItemName(name, slot) + assert(type(name) == "string", "tag must be a string") + assert(type(slot) == "number" and slot > 0 and slot <= 16, "slot must be between 1 and 16") + if self.inv[slot] == nil then + self:log("self.inv is empty at slot "..tostring(slot)) + return false + end + if self.inv[slot].name == nil then + self:log("no name found") + return false + end + if name == "any" then + return true + end + if self.inv[slot].name == name then + return true + else + return false + end +end + +function Wood:updateInv() + self.inv = {} + for slot = 1, 16 do + self.inv[slot] = turtle.getItemDetail(slot, true) + end +end + +function Wood:isInvEmpty(update) + self:assertInvUpdate(update) + for i = 1, 16 do + if (self.inv[i] ~= nil) then + return false + end + end + return true +end + +function Wood:assertInvUpdate(update) + if (update ~= false) then update = true end + + if self.inv == nil then + update = true + end + + assert(type(update) == "boolean","update must be of the type boolean") + if update == true then + self:updateInv() + end +end \ No newline at end of file