minecraft-cc-tools/mystical-upgrader.lua

277 lines
5.3 KiB
Lua

local turtleUtils = require('libs/turtle-utils')
local NB_ROWS = 1
local DIRECTION = 'right' -- 'left' | 'right'
local FILL_BLOCK = 'minecraft:cobblestone'
local LEVEL_PER_TIER = 12
local formatBlockName = function(tierName)
return "mysticalagriculture:" .. tierName .. "_growth_accelerator"
end
local BLOCKS_PER_TIER = {
formatBlockName('inferium'),
formatBlockName('prudentium'),
formatBlockName('tertium'),
formatBlockName('imperium'),
formatBlockName('supremium')
}
local MAX_LEVEL = LEVEL_PER_TIER * #BLOCKS_PER_TIER
local countItems = function(itemName)
local total = 0
for i=1,16,1 do
local details = turtle.getItemDetail(i)
if details and details.name == itemName then
total = total + details.count
end
end
return total
end
local assertEnoughFillBlocks = function()
local count = countItems(FILL_BLOCK)
if count < MAX_LEVEL then
error('Not enough fill blocks, please provide at least ' .. MAX_LEVEL .. ' of ' .. FILL_BLOCK)
end
end
local assertEnoughFuel = function()
local minFuel = 10 + (MAX_LEVEL * 2)
if turtle.getFuelLevel() < minFuel then
error('Not enough fuel')
end
end
local refuel = function()
for i=1, 16, 1 do
local count = turtle.getItemCount(i)
if count > 0 then
turtle.select(i)
turtle.refuel()
end
end
end
local goToTheLeft = function()
turtle.turnLeft()
local ok, reason = turtle.forward()
if not ok then
error('cannot forward because ' .. tostring(reason), 0)
end
turtle.turnRight()
end
local goToTheRight = function()
turtle.turnRight()
local ok, reason = turtle.forward()
if not ok then
error('cannot forward because ' .. tostring(reason), 0)
end
turtle.turnLeft()
end
local MOVES = {
left = goToTheLeft,
right = goToTheRight,
}
local getTierFromLevel = function(level)
return math.floor((level - 1) / LEVEL_PER_TIER) + 1
end
local getBlockNameFromLevel = function(level)
local tier = getTierFromLevel(level)
return BLOCKS_PER_TIER[tier]
end
local inspectBlockName = function()
local ok, block = turtle.inspect()
if not ok then
return nil
end
return block and block.name
end
local selectItem = function(itemName)
for i=1, 16, 1 do
local details = turtle.getItemDetail(i)
if details and details.name == itemName then
turtle.select(i)
return true
end
end
return false
end
local replaceBlockAt = function(y)
local blockName = getBlockNameFromLevel(y);
if inspectBlockName() == blockName then
return false
end
local selected = selectItem(blockName)
if not selected then
return 'error'
end
turtle.dig()
turtle.place()
return true
end
local placeDownFillBlock = function()
selectItem(FILL_BLOCK)
turtle.placeDown()
end
local placeDownItem = function(itemName)
if selectItem(itemName) then
turtle.placeDown()
else
placeDownFillBlock()
end
end
-- Main state and stateful methods
local function getInitialState()
return {
firstPickedItem = nil,
y = 1,
initialLevel = 0,
newLevel = 0,
errorLevel = nil
}
end
-- local state = getInitialState()
local digAndGoDown = function(state)
turtle.digDown()
turtle.down()
state.y = state.y + 1
end
local goUp = function(state)
turtle.up()
state.y = state.y - 1
end
local function tryToSelectEmptySlot()
if not turtleUtils.selectFirstEmptySlot() then
turtleUtils.compactInventory()
if not turtleUtils.selectFirstEmptySlot() then
error('Fatal error: turtle inventory is full', 0)
end
end
end
-- 1. down procedure
local downProcedure = function(state)
while state.y < 60 do
local replaced = replaceBlockAt(state.y)
if replaced == false then
state.initialLevel = state.y
state.newLevel = state.initialLevel
end
if replaced == true then
state.newLevel = state.y
end
if replaced == 'error' then
state.errorLevel = state.y
break
end
if not state.firstPickedItem then
tryToSelectEmptySlot()
digAndGoDown(state)
local item = turtle.getItemDetail(turtle.getSelectedSlot())
-- consider FILL_BLOCK if no block was picked
state.firstPickedItem = (item and item.name) or FILL_BLOCK
else
digAndGoDown(state)
end
end
end
-- 2. up procedure
local upProcedure = function(state)
local firstY = getInitialState().y
while state.y ~= firstY do
goUp(state)
if state.y == firstY and state.firstPickedItem then
placeDownItem(state.firstPickedItem)
else
placeDownFillBlock()
end
end
end
-- 3. print report
local printReport = function(state)
local initialLevel = state.initialLevel
if initialLevel == nil then
initialLevel = 'nil'
end
print('Initial Level: ' .. initialLevel)
print('New Level: ' .. state.newLevel)
if state.errorLevel then
local tier = getTierFromLevel(state.errorLevel)
print('Tier ' .. tier .. ' needed for next upgrade')
end
end
local upgradeProcedure = function()
turtleUtils.compactInventory()
local state = getInitialState()
downProcedure(state)
upProcedure(state)
printReport(state)
return state
end
-- Main function
local main = function()
assertEnoughFillBlocks()
refuel()
assertEnoughFuel()
for i=1, NB_ROWS, 16 do
upgradeProcedure()
if i ~= NB_ROWS then
MOVES[DIRECTION]()
end
end
end
main()