Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local PROGRAM_VERSION = "1.8"
- -- TODO: extract functions into here to be used
- -- apparently args can be dynamically generated ie `function(...)` would take any number of args and store them in a table
- -- you can also specifiy args like `function(arg1, arg2, ...) now we have 2 predefined args and any number after
- -- checks if fuel is needed then consumes fuel if it is
- -- arg1 = #fuel to use, arg2 = minimum fuel before refuelling (upon checking)
- -- TODO: move into a more global robot lib rather than mining specific
- -- TODO: new refuel logic, consume whats needed, maybe based on distance, have checks at startup to ensure enough fuel is always present, otherwise only refuel as needed
- -- TODO: use `cc.inventory` module to check if inventories arent full, could also use this to pull fuel from enderchest if needed
- -- TODO: when mining check if any inventory blocks are infront (loot chests etc.) and then run a function to search them for loot table items that we want to extract
- -- TODO: add configuration to stripmine first run logic to prompt user for which chests are import and export OR none
- -- TODO: maneuver around unbreakable blocks like bedrock
- -- searches inventory for a fuel item then consumes
- -- returns true/false if consumed, fuelRemaining
- function findAndRefuel()
- local fuelStack, isFuel
- for slot=1,wLibVariables.SLOT_COUNT,1 do
- fuelStack = turtle.getItemDetail(slot)
- for i, v in ipairs(FUEL_ITEM) do
- if (fuelStack ~= nil) and (fuelStack["name"] == v) then
- turtle.select(slot)
- isFuel = true
- end
- if(isFuel == true) then break end
- end
- if(isFuel == true) then break end
- end
- if (isFuel) then
- if (fuelStack["count"] >= 3) then
- turtle.refuel(3)
- else
- turtle.refuel(1)
- end
- elseif (isFuel == nil) then
- isFuel = false
- end
- local currentFuel = turtle.getFuelLevel()
- return isFuel, currentFuel
- end
- function checkFuel(isImportChest, importChestSlot)
- isImportChest = isImportChest or false
- importChestSlot = importChestSlot or nil
- local enderChestType = 0 -- import chest
- local isFuel
- if(turtle.getFuelLevel() == 0) then
- sortInventory()
- local currentFuel = turtle.getFuelLevel()
- print("Fuel is low, Current fuel:"..currentFuel)
- print("Refuelling...")
- isFuel, currentFuel = findAndRefuel()
- if (not isFuel) then
- if isImportChest then
- isImportChest, importChestSlot = importFuelEnder(isImportChest, importChestSlot)
- currentFuel = turtle.getFuelLevel()
- elseif (not isImportChest) then
- print("Out of fuel!")
- --TODO: pause this until turlte inventory updated, then run this function again to refuel. That way progress can be kept on mining strip, will work for persistent versions aswell as normal ones
- -- this way a player or turtle can give the turtle fuel to keep it going
- print("No import chest, waiting for user to fix fuel and restart")
- os.pullEvent("key_up")
- os.reboot()
- end
- end
- print("Refueled! Fuel is now:"..currentFuel)
- else
- -- print("Fuel levels are fine, resuming task")
- end
- return isImportChest, importChestSlot, enderChestType
- end
- -- Inventory sorting program to keep stacks together to save space
- -- TODO: move into a more global robot lib rather than mining specific - for the old version that didnt do ender chest checks
- -- TODO: newer versions don't use "damage" need to update to handle that
- function sortInventory()
- local stackOne, stackTwo
- print("Organizing Inventory")
- for slot=1,wLibVariables.SLOT_COUNT-1,1 do
- stackOne = turtle.getItemDetail(slot)
- if(stackOne~=nil) and (turtle.getItemSpace(slot) > 0) then
- for slotTwo=slot+1,wLibVariables.SLOT_COUNT,1 do
- turtle.select(slotTwo)
- stackTwo = turtle.getItemDetail(slotTwo)
- if(stackTwo~=nil) then
- if(stackOne["name"] == stackTwo["name"]) and (stackOne["damage"] == stackTwo["damage"]) then
- local reservedItemSlot = false -- ensure not breaking memory of items stored in reserved slots
- if ( ((slot == 15)) or ((slotTwo == 15) or (slotTwo == 16)) ) then --reserved slots
- for enderInventoryIndex=1,#wLibVariables.ENDER_INVENTORIES,1 do
- if (stackOne["name"] == wLibVariables.ENDER_INVENTORIES[enderInventoryIndex]) then
- reservedItemSlot = true -- reserved items, currently only enderInventories, should expand too chests aswell?
- end
- end
- end
- if (not reservedItemSlot) then --if not reserved item, then stack together
- local stackSpace = turtle.getItemSpace(slot)
- if (stackSpace ~= 0) then
- if (stackSpace <= stackTwo["count"]) then
- turtle.transferTo(slot)
- else
- turtle.transferTo(slot, stackSpace)
- end
- end
- end
- end
- end
- end
- end
- end
- print("Organizing Complete!")
- end
- -- Cleans out inventory of items not in tables
- -- aimed at mining turtles
- function dropItems()
- print("Dropping Waste Inventory")
- for slot=1,wLibVariables.SLOT_COUNT,1 do
- local item = turtle.getItemDetail(slot)
- local keepItem = false
- if(item~=nil) then
- for keepItemIndex=1,#wLibVariables.MINING_KEEP_ITEMS,1 do
- if(item["name"] == wLibVariables.MINING_KEEP_ITEMS[keepItemIndex]) then
- keepItem = true
- break
- end
- end
- for fuelItemIndex=1,#wLibVariables.FUEL_ITEM,1 do
- if(item["name"] == wLibVariables.FUEL_ITEM[fuelItemIndex]) then
- keepItem = true
- break
- end
- end
- for exportInventoriesIndex=1,#wLibVariables.EXPORT_INVENTORIES,1 do
- if(item["name"] == wLibVariables.EXPORT_INVENTORIES[exportInventoriesIndex]) then
- keepItem = true
- break
- end
- end
- if(not keepItem) then
- turtle.select(slot)
- turtle.dropDown()
- end
- end
- end
- print("Waste Dropping Completed")
- sortInventory()
- end
- -- Custom detect that ignores pollution, achieves similar result as how turtle.detect() ignores water/lava
- -- returns true if any non-pollution block detected
- function detectIgnorePollution(direction)
- direction = tonumber(direction) or 0 -- 0=forward, 1=up, 2=down
- local isDetect
- --TODO: validate direction is valid (0,1,2)
- -- Detect if block exists
- if (direction == 0) then
- isDetect = turtle.detect()
- elseif (direction == 1) then
- isDetect = turtle.detectUp()
- elseif (direction == 2) then
- isDetect = turtle.detectDown()
- end
- -- If block exists then filter out pollution
- if (isDetect) then
- local var, block
- if (direction == 0) then
- var, block = turtle.inspect()
- elseif (direction == 1) then
- var, block = turtle.inspectUp()
- elseif (direction == 2) then
- var, block = turtle.inspectDown()
- end
- for pollutionBlocksIndex=1, #wLibVariables.POLLUTION_BLOCKS, 1 do
- if (block.name == wLibVariables.POLLUTION_BLOCKS[pollutionBlocksIndex]) then
- isDetect = false -- if pollution then 'nothing' detected since it acts like air mostly
- end
- end
- end
- return isDetect
- end
- -- to dig, loop stops after 1 round as no block is detected infront!
- -- for strip mines
- function detectAndDigStrip()
- --while turtle detects a block above OR below OR in front, that isn't pollution //logic
- local isMine = true
- local isMineUp = true
- local isMineDown = true
- while (((isMine == true) or (isMineUp == true) or (isMineDown == true))) do
- local var1, block = turtle.inspect()
- local var2, blockUp = turtle.inspectUp()
- local var3, blockDown = turtle.inspectDown()
- for unbreakableIndex=1, #wLibVariables.UNBREAKABLE_BLOCKS, 1 do
- if block.name == wLibVariables.UNBREAKABLE_BLOCKS[unbreakableIndex] then
- isMine = false
- end
- if blockUp.name == wLibVariables.UNBREAKABLE_BLOCKS[unbreakableIndex] then
- isMineUp = false
- end
- if blockDown.name == wLibVariables.UNBREAKABLE_BLOCKS[unbreakableIndex] then
- isMineDown = false
- end
- end
- if ((isMine == true) and (turtle.detect())) then
- turtle.dig()
- elseif (not turtle.detect()) then
- isMine = false
- end
- if ((isMineUp == true) and (turtle.detectUp())) then
- turtle.digUp()
- elseif (not turtle.detectUp()) then
- isMineUp = false
- end
- if ((isMineDown == true) and (turtle.detectDown())) then
- turtle.digDown()
- elseif (not turtle.detectDown()) then
- isMineDown = false
- end
- end
- end
- function detectAndDigUp()
- local isMine = true
- while isMine do
- local var, block = turtle.inspectUp()
- for unbreakableIndex=1, #wLibVariables.UNBREAKABLE_BLOCKS, 1 do
- if block.name == wLibVariables.UNBREAKABLE_BLOCKS[unbreakableIndex] then
- isMine = false
- end
- end
- if ((isMine == true) and (turtle.detectUp())) then
- turtle.digUp()
- elseif (not turtle.detectUp()) then
- isMine = false
- end
- end
- end
- -- Checks if an EXPORT_INVENTORY is infron then Deposit items into chest
- -- adjust so it returns booleans instead of changing the cycles so that start() handles setting the cycle instead
- -- TODO: move into a more global robot lib rather than mining specific
- -- TODO: make a check to see if there is space spaces and/or spare stack space to put items in
- function depositInventory()
- local isBlock, block = turtle.inspect()
- local isExportInventory
- print("Attempting to deposit inventory")
- if (isBlock) then
- for i, v in ipairs(wLibVariables.EXPORT_INVENTORIES) do
- if (block["name"] == v) then
- print("Depositing into "..block["name"])
- isExportInventory = true
- -- exportInventoryMining()
- return isExportInventory -- TODO: turn this into returning an int which is linked to a table of error codes, ie exit codes
- else
- if(i == #wLibVariables.EXPORT_INVENTORIES) and (block["name"] ~= v) then
- print(block["name"].." is not a valid block!")
- print("Stopping stripMine")
- return false -- TODO: turn this into returning an int which is linked to a table of error codes, ie exit codes
- end
- end
- if(isExportInventory == true) then break end
- end
- else
- print("Error: No block detected")
- print("STOPPING stripMine!!!")
- return false -- TODO: turn this into returning an int which is linked to a table of error codes, ie exit codes
- end
- end
- -- Places down a valid inventory item from the EXPORT_INVENTORIES table, in future make a placeInventoryEnder() function which uses ender chests, that function can be used while mining rather than at end of cycles
- -- TODO: move into a more global robot lib
- -- TODO: use reserved slots, saves time searching for inventories, allows removing excess inventories that are aquired
- function placeInventoryLocal()
- local inventoryItem, isInventory
- for slot=1,wLibVariables.SLOT_COUNT,1 do
- inventoryItem = turtle.getItemDetail(slot)
- for i, v in ipairs(wLibVariables.EXPORT_INVENTORIES) do
- if (inventoryItem ~= nil) and (inventoryItem["name"] == v) then
- turtle.select(slot)
- isInventory = true
- -- TODO: add logic to check if there is already an inventory block there
- while(turtle.detect()) do
- turtle.dig()
- end
- print("Placing Inventory: "..inventoryItem["name"])
- turtle.place()
- end
- if(isInventory == true) then break end
- end
- if(isInventory == true) then break end
- end
- end
- -- Checks each slot of the turtle to see if the item should be kept or not
- -- to be used in the middle of mining, separate function should be used to export into an actual base/ME system
- -- such a function would be simply called exportInventory(), or exportInventoryAll()
- -- TODO: needs logic to only keep a certain amount of inventories on hand (inventories could be set by cycles) (similar to fuel)
- function exportInventoryMining(direction)
- direction = tonumber(direction) or 0
- local isFirstFuelstack = true
- for slot=1,wLibVariables.SLOT_COUNT,1 do
- local item = turtle.getItemDetail(slot)
- local keepItem = false
- if (item ~= nil) then
- if((isFirstFuelstack)) then -- exports any excess fuel, keeps half a stack so inventory slot isn't wasted on stackable fuels
- for fuelItemIndex=1,#wLibVariables.FUEL_ITEM,1 do
- if(item["name"] == wLibVariables.FUEL_ITEM[fuelItemIndex]) then
- local firstFuelStacksize = item["count"]
- if (firstFuelStacksize > 32) then
- local exportSize = firstFuelStacksize - 32
- turtle.select(slot)
- if (not dropDirection(direction, exportSize)) then
- print("Export inventory full or missing")
- return false
- end
- end
- keepItem = true
- isFirstFuelstack = false
- break
- end
- end
- end
- for exportInventoriesIndex=1,#wLibVariables.EXPORT_INVENTORIES,1 do
- if(item["name"] == wLibVariables.EXPORT_INVENTORIES[exportInventoriesIndex]) then
- --TODO: update stripMine to only store any/all inventories in particular slots, then we can export them if not there (e.g. unneeded extras obtained somehow)
- if (slot < 15) then -- if ender inventory is found in wrong slot export it
- local isEnder = false
- for enderInventoriesIndex=1,#wLibVariables.ENDER_INVENTORIES,1 do
- if (item["name"] == wLibVariables.ENDER_INVENTORIES[enderInventoriesIndex]) then
- isEnder = true
- break
- end
- end
- if not isEnder then --if inventory is ender then keepItem=false (default)
- keepItem = true -- if NOT ender inventory, we already know it is an inventory so keep it
- end
- break -- need to stop the loop and move onto next slot, of it was an ender inventory in the wrong slot it drops the inventory
- else -- if slot==15or16 and IS an inventory (any)
- keepItem = true
- break
- end
- end
- end
- if(not keepItem) then
- turtle.select(slot)
- if (not dropDirection(direction)) then
- print("Export inventory full or missing")
- return false
- end
- end
- end
- end
- print("Finished exporting inventory")
- return true
- end
- -- check for # of empty slots
- -- returns true if empty slots >= minEmpty
- function emptySlots(minEmpty)
- minEmpty = tonumber(minEmpty)
- local slots = 16
- for i=1,wLibVariables.SLOT_COUNT,1 do
- if (turtle.getItemCount(i) > 0) then
- slots = slots - 1
- end
- end
- if (slots < minEmpty) then
- print("Inventory Full")
- return false
- end
- if (slots >= minEmpty) then
- return true
- end
- end
- -- Digs block infront of turtle to a specific slot in inventory
- -- returns whether successful and slot number
- function digToSlot(direction, slot)
- -- 0/nil = forward, 1 = up, 2 = down
- direction = tonumber(direction) or nil
- slot = tonumber(slot) or nil
- local isItem, itemSlot, tempSlot = false, nil, nil
- --TODO: better logic that can try stacking like items together, or run sortinventory()?
- if (slot ~= nil) then
- turtle.select(slot)
- if (turtle.getItemCount(slot) > 0) then
- for i=1,wLibVariables.SLOT_COUNT-2,1 do --don't attempt to transfer into slots 15/16 as they are reserved
- if (i ~= slot) then
- if (turtle.getItemCount(i) == 0) then
- if (turtle.transferTo(i)) then
- tempSlot = slot
- break -- if successful in transferring items then stop looping
- end
- end
- end
- end
- elseif (turtle.getItemCount(slot) == 0) then
- tempSlot = slot
- end
- elseif (slot == nil) then
- for i=1,wLibVariables.SLOT_COUNT-2,1 do
- local item = turtle.getItemDetail(i)
- if (item == nil) then
- turtle.select(i)
- tempSlot = i
- break
- end
- end
- end
- if ((direction == 0) or (direction == nil)) then
- if (turtle.dig()) then
- itemSlot = tempSlot
- isItem = true
- end
- elseif (direction == 1) then
- if (turtle.digUp()) then
- itemSlot = tempSlot
- isItem = true
- end
- elseif (direction == 2) then
- if (turtle.digDown()) then
- itemSlot = tempSlot
- isItem = true
- end
- end
- return isItem, itemSlot
- end
- --suck from direction, inputs, direction, stacksize
- -- returns true if successful, false if failed
- function suckDirection(direction, size)
- direction = tonumber(direction) or 0
- size = tonumber(size) or nil
- local isSuck
- if (direction == 0) then
- isSuck = turtle.suck(size)
- elseif (direction == 1) then
- isSuck = turtle.suckUp(size)
- elseif (direction == 2) then
- isSuck = turtle.suckDown(size)
- end
- return isSuck
- end
- --Drop to direction, inputs, direction, stacksize
- -- returns true if successful, false if failed
- function dropDirection(direction, size)
- direction = tonumber(direction) or 0
- size = tonumber(size) or nil
- local isDrop
- if (direction == 0) then
- isDrop = turtle.drop(size)
- elseif (direction == 1) then
- isDrop = turtle.dropUp(size)
- elseif (direction == 2) then
- isDrop = turtle.dropDown(size)
- end
- return isDrop
- end
- -- tries to place a block from an inputed slot, attempts to do so from all 6 faces from the turtle
- -- returns is the block is placed, and number of turns the turtle done (for re-orienting to original direction)
- -- TODO: logic to check block being placed isn't already placed? (maybe this should be more of a logic flow control in stripMine)
- function selectAndPlaceOrient(slot)
- slot = slot or nil
- local isItem, itemSlot
- local item = turtle.getItemDetail(slot)
- if (item ~= nil) then
- --TODO: logic to error safely if no item is provided, will also help ensure returns at end of funtion are correct
- isItem, itemSlot = true, slot
- end
- local turns = 0
- local direction = 0 -- 0=forward, 1=up, 2=down, direction block is placed
- if ((slot ~= nil) and (item ~= nil)) then
- local isValid = false
- --TODO: custom detect function that ignores pollution
- -- find suitable position to place block
- for i=1,4,1 do
- if (not detectIgnorePollution(0)) then
- isValid = true
- break
- end
- if (i==1) then -- if not turned yet then check if block above/below is suitable, if so break loop
- if (not detectIgnorePollution(1)) then
- isValid = true
- direction = 1
- break
- elseif (not detectIgnorePollution(2)) then
- isValid = true
- direction = 2
- break
- end
- end
- if (detectIgnorePollution(0)) then
- turtle.turnRight()
- turns = turns + 1
- end
- end
- if (not isValid) then
- turns = 0
- -- ensure space in inventory, incase we mine something good
- if (not emptySlots(3)) then
- dropItems() -- no way to tell is exportChest present, so have to drop items
- end
- for i=1,4,1 do
- if (detectIgnorePollution(0)) then
- detectAndDigStrip()
- end
- if (i==1) then -- if not turned yet then check if block above/below is suitable, if so break loop
- if (not detectIgnorePollution(1)) then
- direction = 1
- break
- elseif (not detectIgnorePollution(2)) then
- direction = 2
- break
- end
- end
- if (detectIgnorePollution(0)) then
- turtle.turnRight()
- turns = turns + 1
- elseif (not detectIgnorePollution(0)) then --if suitable to place block then break loop
- break
- end
- end
- if (not emptySlots(3)) then --Incase many items were obtained while finding a spot for chest (e.g. breaking an instanced chest could fill inventory in one go)
- dropItems()
- end
- end
- -- place block in first direction which was available
- turtle.select(slot)
- if (direction == 0) then
- if (turtle.place()) then
- isItem = false
- itemSlot = nil
- end
- elseif (direction == 1) then
- if (turtle.placeUp()) then
- isItem = false
- itemSlot = nil
- end
- elseif (direction == 2) then
- if (turtle.placeDown()) then
- isItem = false
- itemSlot = nil
- end
- end
- -- if block hasnt been placed then error
- if (isItem) then
- print("error placing chest. No valid positions")
- os.pullEvent("key_up")
- end
- end
- return isItem, itemSlot, turns, direction
- end
- --input number of turns, function takes that and makes turtle face original direction
- -- assumes turtle turned Right to reach current position, which is how selectAndPlaceOrient() works
- function reOrientTurns(turns)
- turns = turns or nil
- if (turns ~= nil) then
- if (turns > 0) then
- if (turns == 3) then
- turtle.turnRight()
- elseif (turns < 3) then
- for i=1,turns,1 do
- turtle.turnLeft()
- end
- end
- end
- end
- end
- --TODO: use depositInventory() function to ensure inventory was placed infront
- -- inputs, isImport - import chest exists in inventory, importChest - slot number for importChest
- -- returns, isImport - does import chest exist in inventory, importChest - slot number for importChest
- --TODO: check inventory is actually in the slot before trying anything, if not then return false, nil and print a msg informing user
- function importFuelEnder(isImport, importChest)
- isImport = isImport or false
- importChest = importChest or nil
- local enderChestType = 0
- --TODO: check item in slot is a valid ender inventory, should solve related problems with helper functions
- if (isImport) then
- if (importChest ~= nil) then
- local isImported = false
- local turns, direction
- local digSlot = importChest
- -- place inventory
- isImport, importChest, turns, direction = selectAndPlaceOrient(importChest)
- --TODO: verify block attempting to import from actually is an inventory
- -- TODO: for logic allowing chests from the same mod via reserving slots need to ensure fuel imported is imported to a slot that is NOT the importChest slot
- -- import fuel
- local importSlot
- for i=1,wLibVariables.SLOT_COUNT,1 do
- local item = turtle.getItemDetail(i)
- if (item == nil) then
- turtle.select(i)
- importSlot = i
- break
- end
- end
- while (not isImported) do --tries to import fuel until successful, waiting 5s after each attempt (gives time for system to refill chest)
- -- isImported = turtle.suck(9)
- if (suckDirection(direction, 9)) then
- local importedItem = turtle.getItemDetail(importSlot)
- for i, v in ipairs(FUEL_ITEM) do
- if ((importedItem ~= nil) and (importedItem["name"] == v)) then
- isImported = true
- end
- end
- if ((importedItem ~= nil) and (not isImported)) then --if not fuel return stack to inventory
- local isReturned = false
- while (not isReturned) do -- attempts to return stack until successful, sleeps between failures
- isReturned = dropDirection(direction)
- if (not isReturned) then
- sleep(2)
- end
- end
- end
- end
- if (not isImported) then
- sleep(5)
- end
- end
- -- retrieve inventory, update variables to return at end
- isImport, importChest = digToSlot(direction, digSlot)
- -- re-orientate to original direction
- reOrientTurns(turns)
- -- locate imported fuel and consume some
- if isImported then
- local isFuel = findAndRefuel()
- if (not isFuel) then
- print("Error importing fuel from ender inventory")
- end
- -- elseif (not isImported) then -- can this code ever even be reached? The while loop should prevent this...
- -- print("failed to import fuel")
- -- os.pullEvent("key_up")
- end
- end
- end
- return isImport, importChest, enderChestType
- end
- --TODO: use depositInventory() function to ensure inventory was placed infront
- --TODO: check inventory is actually in the slot before trying anything, if not then return false, nil and print a msg informing user
- function exportInventoryEnder(isExport, exportChest)
- isExport = isExport or false
- exportChest = exportChest or nil
- local enderChestType = 1
- --TODO: check item in slot is a valid ender inventory, should solve related problems with helper functions
- if isExport then
- if (exportChest ~= nil) then
- local turns, direction
- local digSlot = exportChest
- -- place inventory
- isExport, exportChest, turns, direction = selectAndPlaceOrient(exportChest)
- --TODO: verify block attempting to drop to actual is an inventory
- --TODO: need logic to check on each export attempt to check if the chest is still there so loop isnt infinite if chest is broken/stolen mid-execution
- -- may need 2 returns, possibly a number code or string so logic can be applied to exit loop
- --export into inventory, if not full, if full wait and try again
- local isExportFin = false
- while (not isExportFin) do -- attempts to export until successfully exported every valid slot in inventory
- isExportFin = exportInventoryMining(direction)
- if (not isExportFin) then -- only wait if still exporting
- sleep(5) -- wait inbetween failed exports for chest contents to be extracted remotely
- end
- end
- print("Retrieving Export inventory")
- -- retrieve ender chest and note slot, if failed then isExport = false, exportChest = nil
- isExport, exportChest = digToSlot(direction, digSlot)
- -- reOrient to original direction
- reOrientTurns(turns)
- end
- end
- return isExport, exportChest, enderChestType
- end
- return {
- findAndRefuel = findAndRefuel,
- checkFuel = checkFuel,
- sortInventory = sortInventory,
- dropItems = dropItems,
- detectIgnorePollution = detectIgnorePollution,
- detectAndDigStrip = detectAndDigStrip,
- detectAndDigUp = detectAndDigUp,
- depositInventory = depositInventory,
- placeInventoryLocal = placeInventoryLocal,
- exportInventoryMining = exportInventoryMining,
- emptySlots = emptySlots,
- digToSlot = digToSlot,
- suckDirection = suckDirection,
- dropDirection = dropDirection,
- selectAndPlaceOrient = selectAndPlaceOrient,
- reOrientTurns = reOrientTurns,
- importFuelEnder = importFuelEnder,
- exportInventoryEnder = exportInventoryEnder
- }
Add Comment
Please, Sign In to add comment