Initial files

This commit is contained in:
Jef Roosens 2020-12-28 14:45:50 +01:00
parent 1378189ba2
commit 6dc2343ee5
11 changed files with 758 additions and 0 deletions

115
jlib/fuel.lua Normal file
View file

@ -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

28
jlib/input.lua Normal file
View file

@ -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

90
jlib/log.lua Normal file
View file

@ -0,0 +1,90 @@
-- 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" },
filename = nil
}
Logger.__index = Logger
-- 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)
-- Fill in default values where needed
-- TODO find out if this is needed or not
-- for k, v in pairs(Logger) do
-- o[k] = o[k] or Logger[k]
-- end
-- Open file handler
if o.filename then
o._file = open(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.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

32
jlib/mine.lua Normal file
View file

@ -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

50
jlib/move.lua Normal file
View file

@ -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