CCCPaste

ComputerCraft Tree Farm

local TreeFarm = {

    TREE_TYPES = {
        oak = "straight",
        smallOak = "straight",
        birch = "straight",
        spruce = "straight",
        smallBirch = "straight",
        jungle = "straight",
        smallJungle = "straight",
        largeSpruce = "largeSpruce"
    },

    _saplingSlot = 1,
    _bonemealSlot = 2,
    _farmedAmount = 0
}

--[[
Helper Functions
]]

--[[
Constructor
]]
function TreeFarm:new(obj)
    obj = obj or {}
    setmetatable(obj, self)
    self.__index = self
    return obj
end

--[[
Methode to force the turtle forward with dig and then move
]]
local function forceForward()
    turtle.dig()
    turtle.forward()
end

local function forceUp()
    turtle.digUp()
    turtle.up()
end


--[[
Methode to farm one slice of a 2x2 Space either Left or Right Side.
@param side "Left" or "Right"
]]
local function farm2x2(side)
    local other = "Left"
    if side == "Left" then other = "Right" end
    forceForward()
    turtle["turn"..side]()
    turtle.dig()
    turtle["turn"..side]()
    turtle.forward()
    turtle["turn"..other]()
    turtle.dig()
    turtle["turn"..other]()
end

--[[
Methode to detect to wihich side the turtle has to turn to get
the full Tree.
@return side "Left" or "Right"
]]
local function detectTheSide()
    local side
    turtle.turnLeft()
    local hasBlock, data = turtle.inspect()
    if data.tags["minecraft:logs"] then
        side = "Left"
    else
        side = "Right"
    end
    turtle.turnRight()
    return side
end


--[[
Methodes to change the setFarmedAmmount.
@param n number to add or set
]]
function TreeFarm:setFarmedAmmount(n)
    n = n or 0
    self._farmedAmount = n
end

function TreeFarm:addFarmedAmmount(n)
    n = n or 1
    self._farmedAmount = self._farmedAmount + n
end


--[[
Farming only Trees with a Straight Treelog
]]
function TreeFarm:farmStraightTree()
    forceForward()
    self:addFarmedAmmount(1)
    local hasBlock, data = turtle.inspectUp()
    while hasBlock and data.tags["minecraft:logs"] do
        forceUp()
        self:addFarmedAmmount(1)
        hasBlock, data = turtle.inspectUp()
    end
    while not turtle.detectDown() do
        turtle.down()
    end
    turtle.back()
end

--[[
Methode to fell a 2x2 Tree like Spruce.
@param side "Left" or "Right" or Empty[gets it in function]
]]
function TreeFarm:farmLargeSpruceTree(side)
    forceForward()
    local hasBlock, data = turtle.inspectUp()
    while hasBlock and data.tags["minecraft:logs"] do
        side = side or detectTheSide()
        farm2x2(side)
        self:addFarmedAmmount(4)
        hasBlock, data = turtle.inspectUp()
        forceUp()
    end
    farm2x2(side)
    self:addFarmedAmmount(1)
    while turtle.down() do end
    turtle.back()
end

--[[
Farming one Tree from Start to finish
@param type ["oak","birch","spruce","jungle"]
]]
function TreeFarm:farmTree(type)
    if self.TREE_TYPES[type] == "straight" then
        self:farmStraightTree()
    elseif self.TREE_TYPES[type] == "largeSpruce" then
        self:farmLargeSpruceTree()
    end
end

--[[
Methode to use Bonemeal on the Sapling
]]
function TreeFarm:useBonemeal()
    turtle.select(self._bonemealSlot)
    turtle.place()
end

--[[
Methode to place Sapling in front
]]
function TreeFarm:placeSapling()
    turtle.select(self._saplingSlot)
    turtle.place()
end

--[[
Methode to check if the needed Items are in the inventory
]]
function TreeFarm:checkInvetory()
    local data = turtle.getItemDetail(self._saplingSlot)
    if not data or not data.name:match("sapling") then
        return false
    end
    data = turtle.getItemDetail(self._bonemealSlot)
    if not data or not data.name:match("bone_meal") then
        return false
    end
    for i = 1, 16 do
        if turtle.getItemCount(i) == 0 then
            return true
        end
    end
    return false
end

--[[
Methode to Farm a treetype over and over again 
until amount is satisfed. can use Bonemeal.
@param type             Treetype to farm
@param ammount          the ammount to be farmed
@param canUseBonemeal   if Bonemeal should be used to grow
]]
function TreeFarm:farmTrees(type, ammount, canUseBonemeal)
    while self._farmedAmount < ammount do
        if not self:checkInvetory() then
            print("Missing resources or full")
            return
        end
        local hasBlock, data = turtle.inspect()
        if not hasBlock then
            self:placeSapling()
        end
        if hasBlock and data.tags["minecraft:saplings"] and canUseBonemeal then
            self:useBonemeal()
        elseif hasBlock and data.tags["minecraft:logs"] then
            self:farmTree(type)
            print(self._farmedAmount)
        end
    end
end


return TreeFarm