local turtleUtils = require('libs/turtle-utils') local NB_ROWS = 8 local DIRECTION = 'left' -- '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 + NB_ROWS + (MAX_LEVEL * 2 * NB_ROWS) 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 MOVES = { left = function(strictMode) turtle.turnLeft() local ok, reason = turtle.forward() if strictMode and not ok then error('cannot forward because ' .. tostring(reason), 0) end turtle.turnRight() return ok, reason end, right = function(strictMode) turtle.turnRight() local ok, reason = turtle.forward() if strictMode and not ok then error('cannot forward because ' .. tostring(reason), 0) end turtle.turnLeft() return ok, reason end, } 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 baseReport = 'Level ' .. tostring(state.initialLevel) .. ' -> ' .. state.newLevel if state.errorLevel then print (baseReport .. ' (tier ' .. getTierFromLevel(state.errorLevel) .. ')') else print (baseReport) 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, 1 do upgradeProcedure() if i ~= NB_ROWS then MOVES[DIRECTION](true) else MOVES[DIRECTION](false) -- do not throw if cannot move forward end end end main()