271 lines
5.2 KiB
Lua
271 lines
5.2 KiB
Lua
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
|
|
turtleUtils.compactInventory = function()
|
|
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
|
|
end
|
|
|
|
return turtleUtils |