833 lines
17 KiB
Lua
833 lines
17 KiB
Lua
local _VERSION = "1.0.0"
|
|
|
|
local args = table.pack(...)
|
|
local command = args[1]
|
|
|
|
local GOO_BLOCK_PREFIX = "justdirethings:gooblock_tier"
|
|
local MIN_START_FUEL = 50
|
|
local REFUEL_THRESHOLD = 1000
|
|
local WAIT_SECONDS = 2
|
|
local MIN_FEEDING_ITEMS = 4
|
|
local MAX_SUCK_ATTEMPTS = 16
|
|
|
|
local FUEL_ITEMS = {
|
|
"justdirethings:coal_t4",
|
|
"justdirethings:coal_t3",
|
|
"justdirethings:coal_t2",
|
|
"justdirethings:coal_t1",
|
|
"minecraft:coal",
|
|
}
|
|
|
|
local PROCESS_ITEMS = {
|
|
["minecraft:iron_block"] = { tier = 1 },
|
|
["minecraft:coal_block"] = { tier = 1 },
|
|
["mekanism:block_charcoal"] = { tier = 1 },
|
|
["justdirethings:coalblock_t1"] = { tier = 1 },
|
|
["justdirethings:coalblock_t2"] = { tier = 2 },
|
|
["justdirethings:coalblock_t3"] = { tier = 3 },
|
|
["justdirethings:coalblock_t4"] = { tier = 4 },
|
|
["minecraft:gold_block"] = { tier = 2 },
|
|
["minecraft:diamond_block"] = { tier = 3 },
|
|
["minecraft:netherite_block"] = { tier = 4 },
|
|
}
|
|
|
|
local FEEDING_ITEMS_BY_TIER = {
|
|
[1] = { "minecraft:sugar", "minecraft:rotten_flesh" },
|
|
[2] = { "minecraft:nether_wart" },
|
|
[3] = { "minecraft:chorus_fruit" },
|
|
[4] = { "minecraft:sculk" },
|
|
}
|
|
|
|
local DIR_NORTH = 0
|
|
local DIR_EAST = 1
|
|
local DIR_SOUTH = 2
|
|
local DIR_WEST = 3
|
|
|
|
local DIRECTION_DELTAS = {
|
|
[DIR_NORTH] = { x = 0, z = -1 },
|
|
[DIR_EAST] = { x = 1, z = 0 },
|
|
[DIR_SOUTH] = { x = 0, z = 1 },
|
|
[DIR_WEST] = { x = -1, z = 0 },
|
|
}
|
|
|
|
local HOME = { x = -2, y = 0, z = 0, facing = DIR_EAST }
|
|
local GOO_CHECK = { x = -1, y = 0, z = 0, facing = DIR_EAST }
|
|
|
|
local GOO_CHECKS = {
|
|
{ name = "west goo check", x = -1, y = 0, z = 0, facing = DIR_EAST, action = "forward" },
|
|
{ name = "east goo check", x = 1, y = 0, z = 0, facing = DIR_WEST, action = "forward" },
|
|
{ name = "north goo check", x = 0, y = 0, z = -1, facing = DIR_SOUTH, action = "forward" },
|
|
{ name = "south goo check", x = 0, y = 0, z = 1, facing = DIR_NORTH, action = "forward" },
|
|
{ name = "top goo check", x = 0, y = 1, z = 0, facing = DIR_EAST, action = "down" },
|
|
}
|
|
|
|
local TARGETS = {
|
|
{ name = "west side", x = -2, y = 0, z = 0, facing = DIR_EAST, action = "forward" },
|
|
{ name = "east side", x = 2, y = 0, z = 0, facing = DIR_WEST, action = "forward" },
|
|
{ name = "north side", x = 0, y = 0, z = -2, facing = DIR_SOUTH, action = "forward" },
|
|
{ name = "south side", x = 0, y = 0, z = 2, facing = DIR_NORTH, action = "forward" },
|
|
{ name = "top", x = -1, y = 1, z = 0, facing = DIR_EAST, action = "forward" },
|
|
}
|
|
|
|
local position = { x = HOME.x, y = HOME.y, z = HOME.z }
|
|
local facing = HOME.facing
|
|
local loggedBlockedItems = {}
|
|
local placedTargets = {}
|
|
local lastGooTier = nil
|
|
|
|
local function isFlag(name)
|
|
return function(arg)
|
|
return arg == "-" .. name or arg == "--" .. name
|
|
end
|
|
end
|
|
|
|
local isHelpFlag = isFlag("help")
|
|
local isVersionFlag = isFlag("version")
|
|
|
|
local function printUsage()
|
|
print("goo usage:")
|
|
print()
|
|
print("\t\t\tgoo start")
|
|
print("\t\t\tgoo version")
|
|
print("\t\t\tgoo help")
|
|
end
|
|
|
|
if command == "version" or isVersionFlag(command) then
|
|
print("goo v" .. _VERSION)
|
|
return
|
|
end
|
|
|
|
if command == nil or command == "" or command == "help" or isHelpFlag(command) then
|
|
printUsage()
|
|
return
|
|
end
|
|
|
|
if command ~= "start" then
|
|
printUsage()
|
|
return
|
|
end
|
|
|
|
if not turtle then
|
|
error("goo must be run on a turtle")
|
|
end
|
|
|
|
local function hasPickaxeEquipped()
|
|
local left = turtle.getEquippedLeft()
|
|
local right = turtle.getEquippedRight()
|
|
|
|
return (left and string.match(left.name or "", "_pickaxe$") ~= nil)
|
|
or (right and string.match(right.name or "", "_pickaxe$") ~= nil)
|
|
end
|
|
|
|
local function parseGooTier(blockName)
|
|
local tier = string.match(blockName or "", "^" .. GOO_BLOCK_PREFIX .. "(%d+)$")
|
|
|
|
return tonumber(tier)
|
|
end
|
|
|
|
local function isGooBlock(blockName)
|
|
return parseGooTier(blockName) ~= nil
|
|
end
|
|
|
|
local function isProcessBlock(blockName)
|
|
return PROCESS_ITEMS[blockName] ~= nil
|
|
end
|
|
|
|
local function isFuelItem(itemName)
|
|
for i = 1, #FUEL_ITEMS do
|
|
if FUEL_ITEMS[i] == itemName then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function isFeedingItemForTier(itemName, gooTier)
|
|
local feedingItems = FEEDING_ITEMS_BY_TIER[gooTier] or {}
|
|
|
|
for i = 1, #feedingItems do
|
|
if feedingItems[i] == itemName then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function countItem(itemName)
|
|
local count = 0
|
|
|
|
for slot = 1, 16 do
|
|
local item = turtle.getItemDetail(slot)
|
|
|
|
if item and item.name == itemName then
|
|
count = count + item.count
|
|
end
|
|
end
|
|
|
|
return count
|
|
end
|
|
|
|
local function countFeedingItems(gooTier)
|
|
local count = 0
|
|
local feedingItems = FEEDING_ITEMS_BY_TIER[gooTier] or {}
|
|
|
|
for i = 1, #feedingItems do
|
|
count = count + countItem(feedingItems[i])
|
|
end
|
|
|
|
return count
|
|
end
|
|
|
|
local function findItemSlot(itemName)
|
|
for slot = 1, 16 do
|
|
local item = turtle.getItemDetail(slot)
|
|
|
|
if item and item.name == itemName then
|
|
return slot, item
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function hasFreeSlot()
|
|
for slot = 1, 16 do
|
|
if turtle.getItemCount(slot) == 0 then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function getFuelLevel()
|
|
local fuelLevel = turtle.getFuelLevel()
|
|
|
|
if fuelLevel == "unlimited" then
|
|
return nil
|
|
end
|
|
|
|
return fuelLevel
|
|
end
|
|
|
|
local function getRefuelTarget()
|
|
local fuelLimit = turtle.getFuelLimit()
|
|
|
|
if fuelLimit == "unlimited" or fuelLimit >= REFUEL_THRESHOLD then
|
|
return REFUEL_THRESHOLD
|
|
end
|
|
|
|
return fuelLimit
|
|
end
|
|
|
|
local function findFuelSlot()
|
|
for i = 1, #FUEL_ITEMS do
|
|
local slot, item = findItemSlot(FUEL_ITEMS[i])
|
|
|
|
if slot then
|
|
return slot, item
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function turnRight()
|
|
turtle.turnRight()
|
|
facing = (facing + 1) % 4
|
|
end
|
|
|
|
local function turnLeft()
|
|
turtle.turnLeft()
|
|
facing = (facing + 3) % 4
|
|
end
|
|
|
|
local function turnTo(direction)
|
|
while facing ~= direction do
|
|
local rightTurns = (direction - facing) % 4
|
|
|
|
if rightTurns == 3 then
|
|
turnLeft()
|
|
else
|
|
turnRight()
|
|
end
|
|
end
|
|
end
|
|
|
|
local function moveForward()
|
|
if not turtle.forward() then
|
|
return false
|
|
end
|
|
|
|
local delta = DIRECTION_DELTAS[facing]
|
|
position.x = position.x + delta.x
|
|
position.z = position.z + delta.z
|
|
|
|
return true
|
|
end
|
|
|
|
local function moveUp()
|
|
if not turtle.up() then
|
|
return false
|
|
end
|
|
|
|
position.y = position.y + 1
|
|
|
|
return true
|
|
end
|
|
|
|
local function moveDown()
|
|
if not turtle.down() then
|
|
return false
|
|
end
|
|
|
|
position.y = position.y - 1
|
|
|
|
return true
|
|
end
|
|
|
|
local function moveAxis(target, positiveDirection, negativeDirection, axis)
|
|
while position[axis] ~= target do
|
|
if position[axis] < target then
|
|
turnTo(positiveDirection)
|
|
else
|
|
turnTo(negativeDirection)
|
|
end
|
|
|
|
if not moveForward() then
|
|
return false
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local function goTo(target)
|
|
while position.y < target.y do
|
|
if not moveUp() then
|
|
return false
|
|
end
|
|
end
|
|
|
|
while position.y > target.y do
|
|
if not moveDown() then
|
|
return false
|
|
end
|
|
end
|
|
|
|
if not moveAxis(target.x, DIR_EAST, DIR_WEST, "x") then
|
|
return false
|
|
end
|
|
|
|
if not moveAxis(target.z, DIR_SOUTH, DIR_NORTH, "z") then
|
|
return false
|
|
end
|
|
|
|
if target.facing then
|
|
turnTo(target.facing)
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local function mustGoTo(target, description)
|
|
while not goTo(target) do
|
|
print("Cannot reach " .. description .. ". Clear the path and waiting...")
|
|
os.sleep(WAIT_SECONDS)
|
|
end
|
|
end
|
|
|
|
local function goHome()
|
|
mustGoTo(HOME, "home/provider")
|
|
end
|
|
|
|
local function goToGooCheck()
|
|
mustGoTo(GOO_CHECK, "goo check position")
|
|
end
|
|
|
|
local function inspectDirection(action)
|
|
if action == "forward" then
|
|
return turtle.inspect()
|
|
elseif action == "up" then
|
|
return turtle.inspectUp()
|
|
elseif action == "down" then
|
|
return turtle.inspectDown()
|
|
end
|
|
|
|
error("unknown inspect action " .. tostring(action))
|
|
end
|
|
|
|
local function placeDirection(action)
|
|
if action == "forward" then
|
|
return turtle.place()
|
|
elseif action == "up" then
|
|
return turtle.placeUp()
|
|
elseif action == "down" then
|
|
return turtle.placeDown()
|
|
end
|
|
|
|
error("unknown place action " .. tostring(action))
|
|
end
|
|
|
|
local function refuelFromInventory()
|
|
local fuelLevel = getFuelLevel()
|
|
|
|
if not fuelLevel or fuelLevel >= getRefuelTarget() then
|
|
return false
|
|
end
|
|
|
|
local previousSlot = turtle.getSelectedSlot()
|
|
local consumedFuel = false
|
|
|
|
while fuelLevel < getRefuelTarget() do
|
|
local slot, item = findFuelSlot()
|
|
|
|
if not slot then
|
|
break
|
|
end
|
|
|
|
turtle.select(slot)
|
|
|
|
if turtle.refuel(1) then
|
|
consumedFuel = true
|
|
print("Refueled with " .. item.name .. ". Fuel: " .. tostring(turtle.getFuelLevel()))
|
|
fuelLevel = getFuelLevel()
|
|
else
|
|
print("Could not refuel with " .. item.name .. ".")
|
|
break
|
|
end
|
|
end
|
|
|
|
turtle.select(previousSlot)
|
|
|
|
return consumedFuel
|
|
end
|
|
|
|
local function isProviderBelow()
|
|
local ok = turtle.inspectDown()
|
|
|
|
return ok
|
|
end
|
|
|
|
local function pullFromProvider()
|
|
goHome()
|
|
|
|
local pulled = false
|
|
|
|
for _ = 1, MAX_SUCK_ATTEMPTS do
|
|
if not hasFreeSlot() then
|
|
break
|
|
end
|
|
|
|
if turtle.suckDown() then
|
|
pulled = true
|
|
else
|
|
break
|
|
end
|
|
end
|
|
|
|
return pulled
|
|
end
|
|
|
|
local function shouldKeepItem(item, gooTier)
|
|
if isFuelItem(item.name) then
|
|
return true
|
|
end
|
|
|
|
local processItem = PROCESS_ITEMS[item.name]
|
|
|
|
if processItem and processItem.tier <= gooTier then
|
|
return true
|
|
end
|
|
|
|
if isFeedingItemForTier(item.name, gooTier) then
|
|
return countFeedingItems(gooTier) <= MIN_FEEDING_ITEMS
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function depositOutputs(gooTier)
|
|
goHome()
|
|
|
|
local previousSlot = turtle.getSelectedSlot()
|
|
|
|
for slot = 1, 16 do
|
|
local item = turtle.getItemDetail(slot)
|
|
|
|
if item and not shouldKeepItem(item, gooTier) then
|
|
turtle.select(slot)
|
|
|
|
if turtle.dropDown() then
|
|
print("Deposited " .. item.name .. ".")
|
|
else
|
|
print("Could not deposit " .. item.name .. ". Provider may be full.")
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
turtle.select(previousSlot)
|
|
end
|
|
|
|
local function waitForProvider(message)
|
|
if message then
|
|
print(message)
|
|
end
|
|
|
|
repeat
|
|
os.sleep(WAIT_SECONDS)
|
|
until pullFromProvider()
|
|
end
|
|
|
|
local function ensureStartFuel()
|
|
while true do
|
|
local fuelLevel = getFuelLevel()
|
|
|
|
if not fuelLevel or fuelLevel >= MIN_START_FUEL then
|
|
return
|
|
end
|
|
|
|
refuelFromInventory()
|
|
fuelLevel = getFuelLevel()
|
|
|
|
if not fuelLevel or fuelLevel >= MIN_START_FUEL then
|
|
return
|
|
end
|
|
|
|
waitForProvider("Fuel is below " .. tostring(MIN_START_FUEL) .. ". Add fuel to the provider below home.")
|
|
end
|
|
end
|
|
|
|
local function ensureRuntimeFuel()
|
|
local fuelLevel = getFuelLevel()
|
|
|
|
if not fuelLevel then
|
|
return
|
|
end
|
|
|
|
if fuelLevel < getRefuelTarget() then
|
|
refuelFromInventory()
|
|
end
|
|
|
|
fuelLevel = getFuelLevel()
|
|
|
|
while fuelLevel and fuelLevel < MIN_START_FUEL do
|
|
waitForProvider("Fuel is below " .. tostring(MIN_START_FUEL) .. ". Add fuel to the provider below home.")
|
|
refuelFromInventory()
|
|
fuelLevel = getFuelLevel()
|
|
end
|
|
end
|
|
|
|
local function findFeedingSlot(gooTier)
|
|
local feedingItems = FEEDING_ITEMS_BY_TIER[gooTier] or {}
|
|
|
|
for i = 1, #feedingItems do
|
|
local slot, item = findItemSlot(feedingItems[i])
|
|
|
|
if slot then
|
|
return slot, item
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function findEligibleProcessSlot(gooTier)
|
|
for slot = 1, 16 do
|
|
local item = turtle.getItemDetail(slot)
|
|
local processItem = item and PROCESS_ITEMS[item.name]
|
|
|
|
if processItem then
|
|
if processItem.tier <= gooTier then
|
|
return slot, item, processItem
|
|
end
|
|
|
|
local logKey = item.name .. ":" .. tostring(gooTier)
|
|
|
|
if not loggedBlockedItems[logKey] then
|
|
print(
|
|
item.name
|
|
.. " requires goo tier "
|
|
.. tostring(processItem.tier)
|
|
.. ", current tier is "
|
|
.. tostring(gooTier)
|
|
)
|
|
loggedBlockedItems[logKey] = true
|
|
end
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local function inspectGoo()
|
|
for i = 1, #GOO_CHECKS do
|
|
local check = GOO_CHECKS[i]
|
|
|
|
if goTo(check) then
|
|
local ok, inspected = inspectDirection(check.action)
|
|
|
|
if ok then
|
|
local tier = parseGooTier(inspected.name)
|
|
|
|
if tier then
|
|
lastGooTier = tier
|
|
|
|
return tier, inspected, check
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if lastGooTier then
|
|
print("Cannot reach the goo to inspect it. Using last known tier " .. tostring(lastGooTier) .. ".")
|
|
|
|
return lastGooTier, { state = { alive = true } }, nil
|
|
end
|
|
|
|
error("expected a reachable Just Dire Things goo block around the turtle")
|
|
end
|
|
|
|
local function ensureGooAlive()
|
|
while true do
|
|
local gooTier, inspected, check = inspectGoo()
|
|
|
|
if not check or inspected.state and inspected.state.alive == true then
|
|
return gooTier
|
|
end
|
|
|
|
local slot, item = findFeedingSlot(gooTier)
|
|
|
|
if not slot then
|
|
waitForProvider("Goo tier " .. tostring(gooTier) .. " is not alive. Add feeding items to the provider.")
|
|
else
|
|
turtle.select(slot)
|
|
print("Goo tier " .. tostring(gooTier) .. " is not alive. Feeding with " .. item.name .. "...")
|
|
|
|
if not placeDirection(check.action) then
|
|
print("Could not feed the goo. Waiting before retry...")
|
|
os.sleep(WAIT_SECONDS)
|
|
else
|
|
os.sleep(1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function selectProcessItem(gooTier)
|
|
local slot, item = findEligibleProcessSlot(gooTier)
|
|
|
|
if not slot then
|
|
return nil
|
|
end
|
|
|
|
turtle.select(slot)
|
|
|
|
return item
|
|
end
|
|
|
|
local function inspectTarget(target)
|
|
if target.action == "forward" then
|
|
return turtle.inspect()
|
|
elseif target.action == "up" then
|
|
return turtle.inspectUp()
|
|
elseif target.action == "down" then
|
|
return turtle.inspectDown()
|
|
end
|
|
|
|
error("unknown target action " .. tostring(target.action))
|
|
end
|
|
|
|
local function digTarget(target)
|
|
if target.action == "forward" then
|
|
return turtle.dig()
|
|
elseif target.action == "up" then
|
|
return turtle.digUp()
|
|
elseif target.action == "down" then
|
|
return turtle.digDown()
|
|
end
|
|
|
|
error("unknown target action " .. tostring(target.action))
|
|
end
|
|
|
|
local function placeTarget(target)
|
|
if target.action == "forward" then
|
|
return turtle.place()
|
|
elseif target.action == "up" then
|
|
return turtle.placeUp()
|
|
elseif target.action == "down" then
|
|
return turtle.placeDown()
|
|
end
|
|
|
|
error("unknown target action " .. tostring(target.action))
|
|
end
|
|
|
|
local function ensureMiningSpace(gooTier)
|
|
while not hasFreeSlot() do
|
|
depositOutputs(gooTier)
|
|
|
|
if not hasFreeSlot() then
|
|
print("Inventory is full and provider may be full. Waiting...")
|
|
os.sleep(WAIT_SECONDS)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function isTargetQueued(target)
|
|
for i = 1, #placedTargets do
|
|
if placedTargets[i] == target then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function removeQueuedTarget(index)
|
|
table.remove(placedTargets, index)
|
|
end
|
|
|
|
local function goToTarget(target)
|
|
mustGoTo(target, target.name)
|
|
end
|
|
|
|
local function mineQueuedTarget(gooTier)
|
|
if #placedTargets == 0 then
|
|
return false
|
|
end
|
|
|
|
local target = placedTargets[1]
|
|
|
|
goToTarget(target)
|
|
ensureGooAlive()
|
|
goToTarget(target)
|
|
|
|
local ok, inspected = inspectTarget(target)
|
|
|
|
if not ok then
|
|
print("Queued " .. target.name .. " is empty.")
|
|
removeQueuedTarget(1)
|
|
return true
|
|
end
|
|
|
|
if isProcessBlock(inspected.name) then
|
|
return false
|
|
end
|
|
|
|
if isGooBlock(inspected.name) then
|
|
removeQueuedTarget(1)
|
|
return true
|
|
end
|
|
|
|
print("Mining processed " .. target.name .. " block: " .. tostring(inspected.name))
|
|
ensureMiningSpace(gooTier)
|
|
goToTarget(target)
|
|
|
|
if digTarget(target) then
|
|
removeQueuedTarget(1)
|
|
return true
|
|
end
|
|
|
|
print("Could not mine " .. target.name .. ".")
|
|
|
|
return false
|
|
end
|
|
|
|
local function placeAvailableTarget(gooTier)
|
|
for i = 1, #TARGETS do
|
|
local target = TARGETS[i]
|
|
|
|
if not isTargetQueued(target) then
|
|
goToTarget(target)
|
|
ensureGooAlive()
|
|
goToTarget(target)
|
|
|
|
local ok, inspected = inspectTarget(target)
|
|
|
|
if ok then
|
|
if not isProcessBlock(inspected.name) and not isGooBlock(inspected.name) then
|
|
print("Mining existing " .. target.name .. " block: " .. tostring(inspected.name))
|
|
ensureMiningSpace(gooTier)
|
|
goToTarget(target)
|
|
|
|
if digTarget(target) then
|
|
return true
|
|
end
|
|
end
|
|
else
|
|
local item = selectProcessItem(gooTier)
|
|
|
|
if not item then
|
|
return false
|
|
end
|
|
|
|
print("Placing " .. item.name .. " on goo " .. target.name)
|
|
|
|
if placeTarget(target) then
|
|
placedTargets[#placedTargets + 1] = target
|
|
return true
|
|
end
|
|
|
|
print("Could not place " .. target.name .. ".")
|
|
end
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function waitAtOldestTarget()
|
|
if #placedTargets == 0 then
|
|
goToGooCheck()
|
|
else
|
|
goToTarget(placedTargets[1])
|
|
end
|
|
|
|
print("Waiting for goo processing...")
|
|
os.sleep(WAIT_SECONDS)
|
|
end
|
|
|
|
local function startup()
|
|
print("goo started. Layout: provider below turtle, goo two blocks ahead, turtle facing goo.")
|
|
|
|
if not hasPickaxeEquipped() then
|
|
error("goo requires a turtle with a pickaxe equipped")
|
|
end
|
|
|
|
if not isProviderBelow() then
|
|
error("goo requires a provider/deposit barrel below the turtle")
|
|
end
|
|
|
|
pullFromProvider()
|
|
ensureStartFuel()
|
|
end
|
|
|
|
startup()
|
|
|
|
while true do
|
|
ensureRuntimeFuel()
|
|
|
|
local gooTier = ensureGooAlive()
|
|
depositOutputs(gooTier)
|
|
pullFromProvider()
|
|
ensureRuntimeFuel()
|
|
|
|
gooTier = ensureGooAlive()
|
|
local changed = mineQueuedTarget(gooTier)
|
|
|
|
if not changed then
|
|
changed = placeAvailableTarget(gooTier)
|
|
end
|
|
|
|
if not changed then
|
|
if findEligibleProcessSlot(gooTier) then
|
|
waitAtOldestTarget()
|
|
else
|
|
waitForProvider("No eligible process block found. Add inputs to the provider below home.")
|
|
end
|
|
end
|
|
end
|