local turtleUtils = {} local DEFAULT_IDLE_TIME = 2 turtleUtils.getInventory = function(side) side = side or 'front' local inv = peripheral.wrap(side) if inv and peripheral.hasType(inv, 'inventory') then return inv end return nil end turtleUtils.getItemName = function(slotIndex) local item = turtle.getItemDetail(i) return item and item.name end turtleUtils.getItemCount = function(slotIndex) return turtle.getItemCount(slotIndex) end local function waitFor(predicate, sleepTime) sleepTime = sleepTime or DEFAULT_IDLE_TIME while true do local result = predicate() if result ~= nil and result ~= false then return result end os.sleep(sleepTime) end end turtleUtils.waitForInventory = function(side, sleepTime) return waitFor(function() return turtleUtils.getInventory(side) end, sleepTime) end turtleUtils.waitForMatureCrop = function(inspectFn, sleepTime) inspectFn = inspectFn or turtle.inspect return waitFor(function() return turtleUtils.getMatureCrop(inspectFn) end, sleepTime) end turtleUtils.trySuck = function(suckFn, sleepTime) suckFn = suckFn or turtle.suck sleepTime = sleepTime or DEFAULT_IDLE_TIME while not suckFn() do os.sleep(sleepTime) end end turtleUtils.trySuckUp = function() return turtleUtils.trySuck(turtle.suckUp) end turtleUtils.trySuckDown = function() return turtleUtils.trySuck(turtle.suckDown) end turtleUtils.tryDrop = function(dropFn, sleepTime) dropFn = dropFn or turtle.drop sleepTime = sleepTime or DEFAULT_IDLE_TIME while true do if turtle.getItemCount() == 0 then return false end local dropOk = dropFn(); if (dropOk) then return true end os.sleep(sleepTime) end end turtleUtils.tryDropUp = function() return turtleUtils.tryDrop(turtle.dropUp) end turtleUtils.tryDropDown = function() return turtleUtils.tryDrop(turtle.dropDown) end turtleUtils.dropSlot = function(slotIndex, dropFn) dropFn = dropFn or turtle.drop if turtle.getItemCount(slotIndex) == 0 then return false end if turtle.getSelectedSlot() ~= slotIndex then turtle.select(slotIndex) end local ok, err = dropFn() if not ok then return false end return true end turtleUtils.digAll = function() while turtle.dig() do end end turtleUtils.countFreeSlots = function() local freeSlots = 0 for i=1, 16, 1 do if turtle.getItemCount(i) == 0 then freeSlots = freeSlots + 1 end end return freeSlots end turtleUtils.getFuelPercentage = function() return (turtle.getFuelLevel() / turtle.getFuelLimit()) * 100 end turtleUtils.getMatureCrop = function(inspectFn) inspectFn = inspectFn or turtle.inspect local isBlock, block = inspectFn() local blockStateAge = block and block.state and block.state.age if blockStateAge == 7 then return block.name end return nil end turtleUtils.selectFirstEmptySlot = function() for i = 1, 16, 1 do if turtle.getItemCount(i) == 0 then turtle.select(i) return true end end return false end turtleUtils.selectItemByName = function(itemName) for i = 1, 16, 1 do if itemName == turtleUtils.getItemName(i) then turtle.select(i) return true end end return false end turtleUtils.refuel = function(minFuel, suckFn, sleepTime) suckFn = suckFn or turtle.suck sleepTime = sleepTime or DEFAULT_IDLE_TIME if not turtleUtils.selectFirstEmptySlot() then return false, 'turtle inventory is full' end while turtle.getFuelLevel() < minFuel do local suckRes = suckFn() if suckRes then local ok = turtle.refuel() if not ok then return false, 'selected item is not considered as fuel' end else os.sleep(sleepTime) end end return true end turtleUtils.refuelAllFromInventory = function() local initialSelectedSlot = turtle.getSelectedSlot() for i=1, 16, 1 do if turtle.getItemCount(i) > 0 then turtle.select(i) turtle.refuel() end end if turtle.getSelectedSlot() ~= initialSelectedSlot then turtle.select(initialSelectedSlot) end end -- utils function used by "compactInventory" local function getItemsMap() local result = {} for i=1, 16, 1 do local itemName = turtleUtils.getItemName(i) if itemName then local nbSlotUsed = result[itemName] or 0 result[itemName] = nbSlotUsed + 1 end end return result end local function getSlotsWithSpaces(itemName) local slots = {} for i=1, 16, 1 do if turtleUtils.getItemName(i) == itemName then if turtle.getItemSpace(i) > 0 then table.insert(slots, i) end end end return slots end local function compactItem(itemName) while true do local slots = getSlotsWithSpaces(itemName) if #slots < 2 then break end turtle.select(slots[1]) turtle.transferTo(slots[2], turtle.getItemSpace(slots[2])) end end -- Compact the internal turtle inventory (return the number of freed slots) turtleUtils.compactInventory = function() local initialNbFreeSlots = turtle.countFreeSlots() local initialSelectedSlot = turtle.getSelectedSlot() local itemsMap = getItemsMap() for itemName, nbSlotUsed in pairs(itemsMap) do if nbSlotUsed > 1 then compactItem(itemName) end end if initialSelectedSlot ~= turtle.getSelectedSlot() then turtle.select(initialSelectedSlot) end return turtle.countFreeSlots() - initialNbFreeSlots end return turtleUtils