minecraft-cc-tools/tunnels-miner.lua
2024-05-26 13:28:34 +02:00

248 lines
5.6 KiB
Lua

local STATIC_CONFIG = require('config/tunnels')
local turtleUtils = require('libs/turtle-utils')
local IDLE_TIME = 3
local TIME_TO_START = 3
local IDLE_TIME_BETWEEN_TUNNELS = 1
local SPACE_BETWEEN_TUNNELS = 3
local VERSION = "2.0.0"
local MOVES_BY_DIRECTION = {
right = {
turnLeft = turtle.turnLeft,
turnRight = turtle.turnRight
},
left = { -- this is inversed
turnLeft = turtle.turnRight,
turnRight = turtle.turnLeft
}
}
local function noop() end
local function getMoves(config)
return MOVES_BY_DIRECTION[config.DIRECTION]
end
local function getMinFuelNeeded(config)
local fuelMargin = config.FUEL_MARGIN
if config.VEIN_MODE then
fuelMargin = fuelMargin + config.FUEL_MARGIN_VEIN_MODE
end
return (config.DISTANCE_Z * 2) + SPACE_BETWEEN_TUNNELS + fuelMargin
end
local function checkEnoughFuelForTunnel(config)
local minFuelNeeded = getMinFuelNeeded(config)
if turtle.getFuelLevel() < minFuelNeeded then
turtleUtils.refuelAllFromInventory()
return turtle.getFuelLevel() < minFuelNeeded
end
return true
end
local function assertEnoughFuelForTunnel(config)
if not checkEnoughFuelForTunnel(config) then
error('not enough fuel', 0)
end
end
local function assertValidConfig(config)
if config.DIRECTION ~= 'left' and config.DIRECTION ~= 'right' then
error('config.DIRECTION should be "left" or "right"', 0)
end
if config.DISTANCE_Z <= 0 then
error('config.DISTANCE_Z should be a positive number', 0)
end
local minFuelMargin = 6
if config.FUEL_MARGIN < minFuelMargin then
error('config.FUEL_MARGIN cannot be lower than ' .. minFuelMargin)
end
end
local function assertInventoryIsEmpty()
if not turtleUtils.isInventoryEmpty() then
error('turtle inventory should be empty', 0)
end
end
local function printFuelReport(config)
print('> current fuel: ' .. turtleUtils.getFuelPercentage() .. '%')
print('> fuel needed: ' .. turtleUtils.getFuelPercentage(getMinFuelNeeded(config)) .. '%')
end
local function findGroundProcedure()
local foundGround, errMessage = turtleUtils.goGround()
if not foundGround then
error('cannot find the ground because ' .. tostring(errMessage), 0)
end
end
local function digForward(n, cb)
n = n or 1
cb = cb or noop
for i=1, n, 1 do
turtleUtils.forceForward()
turtle.digDown()
cb(i)
end
end
local function isWhitelistedOre(config, block)
local blockName = block and block.name
if config.VEIN_ORES_WHITELIST[blockName] then
return true
end
return false
end
local function inspectWhitelistedOre(config, inspectFn)
local _, block = inspectFn()
return isWhitelistedOre(config, block)
end
local function mineVeinOres(config)
-- 1. front
if inspectWhitelistedOre(config, turtle.inspect) then
turtleUtils.forceForward()
mineVeinOres(config)
turtle.back()
end
-- 2. up
if inspectWhitelistedOre(config, turtle.inspectUp) then
turtleUtils.forceUp()
mineVeinOres(config)
turtle.down()
end
-- 3. down
if inspectWhitelistedOre(config, turtle.inspectDown) then
turtleUtils.forceDown()
mineVeinOres(config)
turtle.up()
end
-- 4. check left
turtle.turnLeft()
if inspectWhitelistedOre(config, turtle.inspect) then
turtleUtils.forceForward()
mineVeinOres(config)
turtle.back()
end
turtle.turnRight()
-- 5. right
turtle.turnRight()
if inspectWhitelistedOre(config, turtle.inspect) then
turtleUtils.forceForward()
mineVeinOres(config)
turtle.back()
end
turtle.turnLeft()
end
local function mineVeinProcedure(config)
if not config.VEIN_MODE then
return
end
mineVeinOres(config)
turtleUtils.forceDown()
mineVeinOres(config)
turtleUtils.forceUp()
end
local function mineTunnelProcedure(config)
local distance = config.DISTANCE_Z
local onMineCb = function() mineVeinProcedure(config) end
digForward(distance, onMineCb)
getMoves(config).turnRight()
digForward(SPACE_BETWEEN_TUNNELS, onMineCb)
getMoves(config).turnRight()
digForward(distance, onMineCb)
end
local function dropAllProcedure(config)
turtleUtils.forceDown()
getMoves(config).turnRight()
-- try to refuel before dropping items
turtleUtils.refuel(getMinFuelNeeded(config), turtle.suck, IDLE_TIME)
turtleUtils.refuelAllFromInventory()
-- drop all items
for i=1, 16, 1 do
local count = turtle.getItemCount(i)
if count > 0 then
turtleUtils.waitForInventory('front', IDLE_TIME)
while turtle.getItemCount(i) and not turtleUtils.dropSlot(i, turtle.drop) do
os.sleep(IDLE_TIME)
end
end
end
getMoves(config).turnLeft()
-- turtleUtils.forceUp()
end
local function goToNextMineProcedure(config)
getMoves(config).turnLeft()
for _=1, SPACE_BETWEEN_TUNNELS, 1 do
turtleUtils.forceForward()
end
getMoves(config).turnLeft()
turtleUtils.forceUp()
end
local function main(config)
assertValidConfig(config)
turtleUtils.refuelAllFromInventory()
assertInventoryIsEmpty() -- Warning here when implementing persistance
printFuelReport(config)
assertEnoughFuelForTunnel(config)
findGroundProcedure()
turtleUtils.forceUp()
assertEnoughFuelForTunnel(config)
print('> Starting tunnels-miner v' .. VERSION .. ' in ' .. TIME_TO_START .. ' seconds...')
os.sleep(TIME_TO_START)
local tunnelNumber = 1
while true do
if tunnelNumber > 1 then
printFuelReport(config)
assertEnoughFuelForTunnel(config)
end
print('> Start mining tunnel number ' .. tostring(tunnelNumber))
mineTunnelProcedure(config)
dropAllProcedure(config)
goToNextMineProcedure(config)
os.sleep(IDLE_TIME_BETWEEN_TUNNELS)
tunnelNumber = tunnelNumber + 1
end
end
main(STATIC_CONFIG)