2023-01-08 11:01:39 +00:00

405 lines
10 KiB
Lua

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)
return hasMore
end
function Wood:getFuelLevel()
return turtle.getFuelLevel()
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
function Wood:refuel(goBack)
if (goBack == nil) then goBack = true end
if(goBack == true) then
goBack = {self.x, self.y, self.z, self.dir}
end
self:clearInv("coalChest")
turtle.select(1)
turtle.suckDown()
turtle.refuel()
self:moveTo(goBack)
end