Merge branch 'develop' into main
commit
ce0c2d122f
|
@ -0,0 +1,2 @@
|
||||||
|
*.log
|
||||||
|
.treefarm.conf
|
|
@ -0,0 +1,85 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
--
|
||||||
|
-- This program lets you dig out a rectangle
|
||||||
|
-- TODO return to surface option
|
||||||
|
-- TODO arbitrary height instead of multiple of 3
|
||||||
|
-- TODO item storage solution
|
||||||
|
|
||||||
|
local logger = require("jlib.log").Logger:new{level = 3, filename = "dig.log"}
|
||||||
|
local input = require("jlib.input")
|
||||||
|
input.logger = logger
|
||||||
|
local move = require("jlib.move").move
|
||||||
|
move.logger = logger
|
||||||
|
local fuel = require("jlib.fuel")
|
||||||
|
fuel.logger = logger
|
||||||
|
|
||||||
|
|
||||||
|
local function layer(width, depth, offset)
|
||||||
|
for i = 1, width do
|
||||||
|
-- Mine slice
|
||||||
|
move('f', depth - 1, { turtle.digUp, turtle.digDown })
|
||||||
|
|
||||||
|
-- Move to next slice
|
||||||
|
if i < width then
|
||||||
|
dir = (i + offset) % 2
|
||||||
|
|
||||||
|
if dir == 0 then turtle.turnLeft() else turtle.turnRight() end
|
||||||
|
move('f', 1, { turtle.digUp, turtle.digDown })
|
||||||
|
if dir == 0 then turtle.turnLeft() else turtle.turnRight() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function dig(width, depth, height, dir)
|
||||||
|
-- Dig initial blocks
|
||||||
|
turtle.digUp()
|
||||||
|
turtle.digDown()
|
||||||
|
|
||||||
|
local layers = height / 3
|
||||||
|
for j = 1, layers do
|
||||||
|
local offset = 0
|
||||||
|
|
||||||
|
if j % 2 == 0 and width % 2 == 0 then offset = 1 end
|
||||||
|
layer(width, depth, offset)
|
||||||
|
-- Move down a layer
|
||||||
|
|
||||||
|
if j < layers then
|
||||||
|
move(dir, 3)
|
||||||
|
if dir == 'd' then turtle.digDown() else turtle.digUp() end
|
||||||
|
turtle.turnLeft()
|
||||||
|
turtle.turnLeft()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function main(args)
|
||||||
|
-- Take inputs
|
||||||
|
local width = tonumber(args[1]) or input.read_int("Width: ")
|
||||||
|
local depth = tonumber(args[2]) or input.read_int("Depth: ")
|
||||||
|
local height = tonumber(args[3]) or input.read_int("Height: ")
|
||||||
|
-- TODO add check for dir
|
||||||
|
local dir = args[4]
|
||||||
|
|
||||||
|
-- Make sure height is valid
|
||||||
|
-- TODO make program work with any height
|
||||||
|
if height % 3 ~= 0 then
|
||||||
|
return logger:log(3, "Height is not a multiple of 3.")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check fuel level
|
||||||
|
-- The + 2 accounts for the moving between layers
|
||||||
|
local fuel_needed = (depth * width + 3) * (height / 3)
|
||||||
|
if not fuel.check(fuel_needed) then
|
||||||
|
return logger:log(1, "Insufficient fuel.")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Do the dig
|
||||||
|
dig(width, depth, height, dir)
|
||||||
|
|
||||||
|
logger:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
main({...})
|
|
@ -0,0 +1,115 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
--
|
||||||
|
-- This module contains functions which ease fuel management in a turtle
|
||||||
|
|
||||||
|
|
||||||
|
-- local turtle = require('turtle')
|
||||||
|
local module = {}
|
||||||
|
module.logger = require("jlib.log").Logger:new{level = -1}
|
||||||
|
|
||||||
|
|
||||||
|
-- Refuel the turtle using the given slot; tries to optimize refuel speed by
|
||||||
|
-- calculating needed refuel count
|
||||||
|
--
|
||||||
|
-- @param slot slot to refuel from
|
||||||
|
-- @param goal refuel goal to reach
|
||||||
|
-- @return wether the refuel was enough
|
||||||
|
function module.refuel_from(slot, goal)
|
||||||
|
-- First, we get the current level
|
||||||
|
local start = turtle.getFuelLevel()
|
||||||
|
|
||||||
|
-- If we've already reached the goal, just return true
|
||||||
|
if start >= goal then return true end
|
||||||
|
|
||||||
|
-- Select the slot and refuel once
|
||||||
|
turtle.select(slot)
|
||||||
|
turtle.refuel(1)
|
||||||
|
|
||||||
|
-- Get the difference
|
||||||
|
local level = turtle.getFuelLevel()
|
||||||
|
local diff = level - start
|
||||||
|
|
||||||
|
-- If the diff is 0 the slot is empty or can't refuel, so return false
|
||||||
|
if diff == 0 then return false end
|
||||||
|
|
||||||
|
-- Calculate needed refuels
|
||||||
|
local needed = math.ceil((goal - level) / diff)
|
||||||
|
|
||||||
|
-- Do the refuel
|
||||||
|
turtle.refuel(needed)
|
||||||
|
|
||||||
|
-- Return wether or not we reached the goal
|
||||||
|
return turtle.getFuelLevel() >= goal
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Check if the turtle has enough fuel; takes a table of preferred items
|
||||||
|
--
|
||||||
|
-- @param goal fuel goal to reach
|
||||||
|
-- @param preferred table containing names of preferred items
|
||||||
|
-- @return wether or not the fuel level was reached
|
||||||
|
function module.check(goal, preferred)
|
||||||
|
-- Convert table to set for faster lookup
|
||||||
|
local set = {}
|
||||||
|
|
||||||
|
if preferred then
|
||||||
|
for _, v in ipairs(preferred) do
|
||||||
|
set[v] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Turtle needs to be able to get down at all times
|
||||||
|
local i, done = 1, turtle.getFuelLevel() >= goal
|
||||||
|
|
||||||
|
-- Instantly quit if it's already good
|
||||||
|
-- This check is mostly useful voor the logging aspect
|
||||||
|
if done then
|
||||||
|
module.logger:info("No refuel needed.")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Store all non-preferred options
|
||||||
|
local options = {}
|
||||||
|
|
||||||
|
-- Iterate over all 16 slots, or stop earlier if possible
|
||||||
|
while not done and i <= 16 do
|
||||||
|
local data = turtle.getItemDetail(i)
|
||||||
|
|
||||||
|
if data and set[data.name] then
|
||||||
|
done = module.refuel_from(i, goal)
|
||||||
|
|
||||||
|
else
|
||||||
|
table.insert(options, i)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Exit if goal has been reached
|
||||||
|
if done then
|
||||||
|
module.logger:info("Refueled using preferred.")
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Process non-preferred options
|
||||||
|
for _, j in pairs(options) do
|
||||||
|
done = module.refuel_from(j, goal)
|
||||||
|
|
||||||
|
if done then
|
||||||
|
module.logger:info("Refueled using non-preferred.")
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module.logger:warning(
|
||||||
|
"Refuel failed. Missing: " .. goal - turtle.getFuelLevel())
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return module
|
|
@ -0,0 +1,28 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
--
|
||||||
|
-- Useful functions for receiving input from the user
|
||||||
|
|
||||||
|
local module = {}
|
||||||
|
module.logger = require("jlib.log").Logger:new{level = -1}
|
||||||
|
|
||||||
|
|
||||||
|
-- Read an integer
|
||||||
|
--
|
||||||
|
-- @param prompt prompt string to show
|
||||||
|
-- @param negative wether or not the number can be negative; defaults to false
|
||||||
|
function module.read_int(prompt, negative)
|
||||||
|
while true do
|
||||||
|
write(prompt)
|
||||||
|
|
||||||
|
local num = tonumber(read())
|
||||||
|
if num and num >= 0 or not negative then
|
||||||
|
module.logger:info("Input: " .. num)
|
||||||
|
return num
|
||||||
|
end
|
||||||
|
|
||||||
|
print("Please enter a valid number.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return module
|
|
@ -0,0 +1,86 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
--
|
||||||
|
-- Module to add logging to a program. This module is integrated in all jlib
|
||||||
|
-- functions.
|
||||||
|
|
||||||
|
|
||||||
|
local module = {}
|
||||||
|
|
||||||
|
|
||||||
|
-- Define class with default values
|
||||||
|
local Logger = {
|
||||||
|
level = 2,
|
||||||
|
level_colors = {
|
||||||
|
colors.red, colors.orange, colors.yellow, colors.blue, colors.white},
|
||||||
|
prefixes = {"CRIT", "ERROR", "WARN", "INFO", "DEBUG"},
|
||||||
|
-- Explicit is better than implicit
|
||||||
|
filename = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
-- Return a new logger 'object'.
|
||||||
|
--
|
||||||
|
-- @param level log level:
|
||||||
|
-- (0) critical, (1) errors, (2) warnings, (3) info,(4) debug
|
||||||
|
-- @param level_colors table containing color names for messages; order is
|
||||||
|
-- { critical, errors, warnings, info, debug }. Only colors for the needed log
|
||||||
|
-- level need to be provided: e.g. if the log level is (2) warnings, then only
|
||||||
|
-- two colors need to be provided. If not provided, defaults to
|
||||||
|
-- { red, orange, yellow, blue, white }.
|
||||||
|
-- @param prefixes prefix to show for each log level
|
||||||
|
-- @param filename log file to write to. If not supplied, log will only be
|
||||||
|
-- outputted to stdout
|
||||||
|
-- @return a logger 'object'
|
||||||
|
function Logger:new(o)
|
||||||
|
o = o or {}
|
||||||
|
setmetatable(o, self)
|
||||||
|
self.__index = self
|
||||||
|
|
||||||
|
-- Open file handler
|
||||||
|
if o.filename then
|
||||||
|
o._file = fs.open(o.filename, "a")
|
||||||
|
end
|
||||||
|
|
||||||
|
return o
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Log a message with the given level
|
||||||
|
--
|
||||||
|
-- @param level log level; levels higher than logger level get discarded
|
||||||
|
-- @param message message to log
|
||||||
|
-- @return wether or not the message was actually logged
|
||||||
|
function Logger:log(level, message)
|
||||||
|
-- Exit if the level is too high
|
||||||
|
if level > self.level then return false end
|
||||||
|
|
||||||
|
-- Log to screen
|
||||||
|
local cur_color = term.getTextColor()
|
||||||
|
term.setTextColor(self.level_colors[level + 1])
|
||||||
|
term.write("[" .. self.prefixes[level + 1] .. "] ")
|
||||||
|
term.setTextColor(cur_color)
|
||||||
|
print(message)
|
||||||
|
|
||||||
|
-- Log to file
|
||||||
|
if self._file then
|
||||||
|
local line = "[" .. self.prefixes[level + 1] .. "] " .. message .. '\n'
|
||||||
|
self._file.write(line)
|
||||||
|
self._file.flush()
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Just some convenience functions; wrappers around Logger:log
|
||||||
|
function Logger:critical(message) self:log(0, message) end
|
||||||
|
function Logger:error(message) self:log(1, message) end
|
||||||
|
function Logger:warning(message) self:log(2, message) end
|
||||||
|
function Logger:info(message) self:log(3, message) end
|
||||||
|
function Logger:debug(message) self:log(4, message) end
|
||||||
|
|
||||||
|
-- Close the logger a.k.a. close the log file handler
|
||||||
|
function Logger:close()
|
||||||
|
if self._file then self._file.close() end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
module.Logger = Logger
|
||||||
|
return module
|
|
@ -0,0 +1,32 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
|
||||||
|
|
||||||
|
local module = {}
|
||||||
|
module.logger = require("jlib.log").Logger:new{level = -1}
|
||||||
|
|
||||||
|
|
||||||
|
-- Safely dig in given direction (aka account for falling blocks)
|
||||||
|
--
|
||||||
|
-- @param dir direction to dig (f, u, d)
|
||||||
|
-- @return amount of blocks it broke
|
||||||
|
function module.dig(dir)
|
||||||
|
local funcs = {
|
||||||
|
f = { turtle.detect, turtle.dig },
|
||||||
|
u = { turtle.detectUp, turtle.digUp },
|
||||||
|
d = { turtle.detectDown, turtle.digDown }
|
||||||
|
}
|
||||||
|
|
||||||
|
local i = 0
|
||||||
|
|
||||||
|
while funcs[dir][1]() do
|
||||||
|
funcs[dir][2]()
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
module.logger:info("Mined " .. i .. " blocks")
|
||||||
|
return i
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return module
|
|
@ -0,0 +1,50 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
--
|
||||||
|
-- Utilities to ease movement using a turtle
|
||||||
|
|
||||||
|
|
||||||
|
local dig = require("jlib.mine").dig
|
||||||
|
local module = {}
|
||||||
|
module.logger = require("jlib.log").Logger:new{level = -1}
|
||||||
|
|
||||||
|
|
||||||
|
-- Safely move n blocks. This means accounting for gravel, trees growing...
|
||||||
|
--
|
||||||
|
-- @param dir direction to move (u, d, f)
|
||||||
|
-- @param n number of blocks to move. If nil (or not supplied), 1 is taken as
|
||||||
|
-- @param side_effect a function/table of functions which gets called after the
|
||||||
|
-- turtle has moved 1 block. This can be used to extend the functionality of
|
||||||
|
-- the function without having to re-write it.
|
||||||
|
function module.move(dir, n, side_effect)
|
||||||
|
-- Default value
|
||||||
|
n = n or 1
|
||||||
|
|
||||||
|
local funcs = {
|
||||||
|
u = turtle.up,
|
||||||
|
d = turtle.down,
|
||||||
|
f = turtle.forward
|
||||||
|
}
|
||||||
|
|
||||||
|
for _ = 1, n do
|
||||||
|
dig(dir)
|
||||||
|
funcs[dir]()
|
||||||
|
|
||||||
|
-- Run the side-effect if given
|
||||||
|
if side_effect then
|
||||||
|
if type(side_effect) == "table" then
|
||||||
|
for _, f in pairs(side_effect) do
|
||||||
|
f()
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
side_effect()
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module.logger:info("Moved " .. n .. " blocks")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
return module
|
|
@ -0,0 +1,100 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
-- TODO: fix bug where if you start a 2x2 tree in the middle, the turtle will still end up on the bottom
|
||||||
|
|
||||||
|
|
||||||
|
local fuel = require('jlib.fuel')
|
||||||
|
local move = require('jlib.move').move
|
||||||
|
|
||||||
|
|
||||||
|
-- Chop a tree in the given direction
|
||||||
|
local function chop(tree_type, two_deep, go_down, return_to_start)
|
||||||
|
local i, data = 0
|
||||||
|
if go_down then _, data = turtle.inspectDown() else _, data = turtle.inspectUp() end
|
||||||
|
|
||||||
|
while data.name == tree_type do
|
||||||
|
-- Make sure we have enough fuel to get back up
|
||||||
|
fuel.check(i + 1)
|
||||||
|
|
||||||
|
if two_deep then turtle.dig() end
|
||||||
|
-- This also mines the block
|
||||||
|
if go_down then move('d') else move('u') end
|
||||||
|
|
||||||
|
i = i + 1
|
||||||
|
if go_down then _, data = turtle.inspectDown() else _, data = turtle.inspectUp() end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Dig one higher. This allows us to chop jungle trees, which often leave one block higher
|
||||||
|
if i > 0 and not go_down then
|
||||||
|
fuel.check(i + 1)
|
||||||
|
if two_deep then turtle.dig() end
|
||||||
|
move('u')
|
||||||
|
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Dig the final block
|
||||||
|
if two_deep then turtle.dig() end
|
||||||
|
|
||||||
|
-- Because we check the fuel level every time, we know for certain we can get back up/down
|
||||||
|
if return_to_start then
|
||||||
|
if go_down then move('u', i) else move('d', i) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Determine tree type
|
||||||
|
local _, data = turtle.inspect()
|
||||||
|
local tree_type = data.name
|
||||||
|
|
||||||
|
if not fuel.check(1) then
|
||||||
|
print("I need 1 fuel to start.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get into position
|
||||||
|
turtle.dig()
|
||||||
|
turtle.forward()
|
||||||
|
|
||||||
|
-- Check if it's a two-deep tree
|
||||||
|
local _, data = turtle.inspect()
|
||||||
|
local two_deep, two_by_two, right = data.name == tree_type, false, false
|
||||||
|
|
||||||
|
-- Check if it's a 2x2 tree
|
||||||
|
if two_deep then
|
||||||
|
turtle.turnRight()
|
||||||
|
local _, data = turtle.inspect()
|
||||||
|
turtle.turnLeft()
|
||||||
|
|
||||||
|
two_by_two = data.name == tree_type
|
||||||
|
|
||||||
|
-- Check if we're on the right side instead
|
||||||
|
if not two_by_two then
|
||||||
|
turtle.turnLeft()
|
||||||
|
_, data = turtle.inspect()
|
||||||
|
turtle.turnRight()
|
||||||
|
|
||||||
|
two_by_two = data.name == tree_type
|
||||||
|
right = two_by_two
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Chop the actual tree
|
||||||
|
-- Chop left half
|
||||||
|
chop(tree_type, two_deep, true, true)
|
||||||
|
-- Come back down if it's not a two_by_two, else don't
|
||||||
|
chop(tree_type, two_deep, false, not two_by_two)
|
||||||
|
|
||||||
|
-- Get into position if it's a two-by-two
|
||||||
|
if two_by_two then
|
||||||
|
if right then turtle.turnLeft() else turtle.turnRight() end
|
||||||
|
turtle.dig()
|
||||||
|
turtle.forward()
|
||||||
|
if right then turtle.turnRight() else turtle.turnLeft() end
|
||||||
|
|
||||||
|
-- Go back down, or dig second half
|
||||||
|
chop(tree_type, two_deep, true, false)
|
||||||
|
|
||||||
|
if right then turtle.turnRight() else turtle.turnLeft() end
|
||||||
|
turtle.forward()
|
||||||
|
if right then turtle.turnLeft() else turtle.turnRight() end
|
||||||
|
end
|
|
@ -0,0 +1,211 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
local logger = require('jlib.log').Logger:new{level=3, filename="treefarm.log"}
|
||||||
|
local fuel = require('jlib.fuel')
|
||||||
|
fuel.logger = logger
|
||||||
|
local move = require('jlib.move').move
|
||||||
|
|
||||||
|
|
||||||
|
-- Chop a 1x1 tree
|
||||||
|
--
|
||||||
|
-- @param max_height height of tallest known tree
|
||||||
|
--
|
||||||
|
-- @return height of chopped tree if greater than known highest, otherwise
|
||||||
|
-- known highest
|
||||||
|
local function chop(max_height, log_name)
|
||||||
|
logger:log(3, "Chopping tree")
|
||||||
|
|
||||||
|
-- Make sure we have enough fuel for the largest known tree
|
||||||
|
fuel.check(2 * max_height + 1, { log_name })
|
||||||
|
|
||||||
|
-- Move one forward
|
||||||
|
move('f')
|
||||||
|
|
||||||
|
turtle.digDown()
|
||||||
|
|
||||||
|
-- Chop up until we no longer find logs
|
||||||
|
local _, data = turtle.inspectUp()
|
||||||
|
|
||||||
|
local height = 0
|
||||||
|
while data.name == log_name do
|
||||||
|
-- These checks most likely always succeed instantly thanks to the
|
||||||
|
-- tallest tree system
|
||||||
|
fuel.check(height, { log_name })
|
||||||
|
|
||||||
|
move('u', 1)
|
||||||
|
_, data = turtle.inspectUp()
|
||||||
|
|
||||||
|
height = height + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Move back down
|
||||||
|
move('d', height)
|
||||||
|
|
||||||
|
-- Return the new height if it's greater than the old
|
||||||
|
|
||||||
|
max_height = math.max(max_height, height)
|
||||||
|
logger:debug("Max height: " .. max_height)
|
||||||
|
|
||||||
|
return max_height
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Select given item
|
||||||
|
--
|
||||||
|
-- @param item_name name of item to select
|
||||||
|
--
|
||||||
|
-- @return wether or not the item could be selected
|
||||||
|
local function select_item(item_name)
|
||||||
|
for i = 1, 16 do
|
||||||
|
local data = turtle.getItemDetail(i)
|
||||||
|
|
||||||
|
if data and data.name == item_name then
|
||||||
|
turtle.select(i)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Do one cycle through the farm
|
||||||
|
--
|
||||||
|
-- @param max_height height of tallest known tree
|
||||||
|
--
|
||||||
|
-- @return new height of tallest known tree
|
||||||
|
local function cycle(width, depth, max_height, sapling_name, log_name,
|
||||||
|
spacing)
|
||||||
|
logger:info("Starting cycle")
|
||||||
|
|
||||||
|
for i = 1, width do
|
||||||
|
-- Check for fuel to go through entire row
|
||||||
|
fuel.check((spacing + 1) * (depth - 1) + 2, { log_name })
|
||||||
|
|
||||||
|
for j = 1, depth do
|
||||||
|
local _, data = turtle.inspect()
|
||||||
|
|
||||||
|
-- Chop down the tree, or move forward
|
||||||
|
if data.name == log_name then
|
||||||
|
-- Gotta re-do the check from the beginning of this row
|
||||||
|
fuel.check(
|
||||||
|
2 * max_height + 1 + (spacing + 1) * (depth - j) + 2,
|
||||||
|
{ log_name })
|
||||||
|
|
||||||
|
max_height = chop(max_height, log_name)
|
||||||
|
|
||||||
|
else
|
||||||
|
move('f')
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Place down a sapling, if possible
|
||||||
|
if select_item(sapling_name) then
|
||||||
|
turtle.placeDown()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Pick up any dropped saplings
|
||||||
|
turtle.suckDown()
|
||||||
|
|
||||||
|
-- Move forward
|
||||||
|
|
||||||
|
if j < depth then
|
||||||
|
move('f', spacing)
|
||||||
|
else
|
||||||
|
move('f')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Turn
|
||||||
|
if i < width then
|
||||||
|
if i % 2 == 0 then turtle.turnLeft() else turtle.turnRight() end
|
||||||
|
fuel.check(spacing + 1, { log_name })
|
||||||
|
move('f', spacing + 1)
|
||||||
|
if i % 2 == 0 then turtle.turnLeft() else turtle.turnRight() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return max_height
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Do maintenance stuff: drop off items, and restock on saplings
|
||||||
|
local function maintenance(width, depth, sapling_name, log_name)
|
||||||
|
logger:info("Doing maintenance")
|
||||||
|
fuel.check(6, { log_name })
|
||||||
|
|
||||||
|
-- Move towards sapling chest
|
||||||
|
move('f')
|
||||||
|
turtle.turnLeft()
|
||||||
|
move('f')
|
||||||
|
|
||||||
|
-- Deposite all saplings
|
||||||
|
while select_item(sapling_name) do turtle.drop(64) end
|
||||||
|
|
||||||
|
-- Get enough saplings
|
||||||
|
turtle.select(1)
|
||||||
|
turtle.suck(width * depth)
|
||||||
|
|
||||||
|
-- Move towards log chest
|
||||||
|
turtle.turnRight()
|
||||||
|
move('f')
|
||||||
|
turtle.turnLeft()
|
||||||
|
|
||||||
|
-- Deposite all logs
|
||||||
|
while select_item(log_name) do turtle.drop(64) end
|
||||||
|
|
||||||
|
-- Keep 10 logs for refueling
|
||||||
|
turtle.select(2)
|
||||||
|
turtle.suck(10)
|
||||||
|
|
||||||
|
-- Get back to start block
|
||||||
|
turtle.turnRight()
|
||||||
|
turtle.turnRight()
|
||||||
|
move('f')
|
||||||
|
turtle.turnRight()
|
||||||
|
move('f', 2)
|
||||||
|
|
||||||
|
logger:info("Maintenance finished")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function main()
|
||||||
|
-- Load the settings, or quit if it fails
|
||||||
|
if not settings.load(".treefarm.conf") then
|
||||||
|
return logger:critical("Couldn't load configuration file. Please make sure it exists and doesn't contain syntax errors.")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get all variables (API calls are slow)
|
||||||
|
local width, depth, spacing, border_width, log_name, sapling_name, delay =
|
||||||
|
settings.get("width"), settings.get("depth"), settings.get("spacing"),
|
||||||
|
settings.get("border_width"), settings.get("log_name"),
|
||||||
|
settings.get("sapling_name"), settings.get("delay")
|
||||||
|
local max_height = 0
|
||||||
|
|
||||||
|
logger:info("Settings loaded")
|
||||||
|
|
||||||
|
-- Start the main loop
|
||||||
|
logger:info("Starting main loop")
|
||||||
|
while true do
|
||||||
|
-- Get into start position for cycle
|
||||||
|
fuel.check(2, { log_name })
|
||||||
|
move('f', 2)
|
||||||
|
|
||||||
|
-- Run through two cycles
|
||||||
|
max_height = cycle(width, depth, max_height, sapling_name, log_name,
|
||||||
|
spacing)
|
||||||
|
turtle.turnRight()
|
||||||
|
turtle.turnRight()
|
||||||
|
sleep(delay)
|
||||||
|
max_height = cycle(width, depth, max_height, sapling_name, log_name,
|
||||||
|
spacing)
|
||||||
|
|
||||||
|
-- Do maintenance and subtract maintenance time from delay
|
||||||
|
fuel.check(border_width, { log_name })
|
||||||
|
move('f', border_width)
|
||||||
|
|
||||||
|
local seconds = os.clock()
|
||||||
|
maintenance(width, depth, sapling_name, log_name)
|
||||||
|
sleep(math.max(0, delay - os.clock() + seconds))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
main()
|
|
@ -0,0 +1,26 @@
|
||||||
|
-- Created by Jef Roosens
|
||||||
|
--
|
||||||
|
-- This script digs a 1x2 tunnel of a given length
|
||||||
|
|
||||||
|
local logger = require("jlib.log").init_logger(3)
|
||||||
|
local fuel = require("jlib.fuel")
|
||||||
|
fuel.logger = logger
|
||||||
|
local move = require("jlib.move").move
|
||||||
|
local input = require("jlib.input")
|
||||||
|
|
||||||
|
|
||||||
|
local function main(args)
|
||||||
|
-- Get tunnel length
|
||||||
|
local length = tonumber(args[1]) or input.read_int("Tunnel length: ")
|
||||||
|
|
||||||
|
-- Check if fuel is sufficient
|
||||||
|
if not fuel.check(length) then
|
||||||
|
return logger:log(1, "Insufficient fuel.")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Do the digging
|
||||||
|
move('f', length, { turtle.digDown, turtle.digUp })
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
main({...})
|
Loading…
Reference in New Issue