Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local fuelMatchSlot=16 -- Slot holding Fuel
- local fuelMin = 10 -- Fuel leverl to trigger refuel
- local fuelRefill = 50 -- Refuel to this amount
- local seedMatchSlot=15 -- Slot holding Seed to plant
- -- Determine Mode and start coroutines
- function main( tArgs )
- local fHandler
- local cmds = ""
- local coGo
- local coFuel
- local status
- local yy
- -- Verify Command Line Arguments were correct
- if #tArgs < 1 then
- print( "Usage: work <routefile> -or-" )
- print( " work <command> <command> ... etc -or-")
- print( " work program")
- return false
- end
- if #tArgs == 2 and tArgs[1] == "program" then
- interactiveMode(tArgs[2])
- return
- end
- -- test if we have a filename or a command
- if fs.exists(tArgs[1]) then
- fileOrCmds = "file"
- else
- fileOrCmds = "cmds"
- end
- -- Read in our command list from the file
- if fileOrCmds == "file" then
- if fs.exists(tArgs[1]) then
- fHandler = fs.open(tArgs[1],"r")
- if fHandler then
- cmds = fHandler.readAll
- end
- end
- else -- Read in our commands from the command line
- -- Convert from a table into a space separated list
- for i,v in ipairs(tArgs) do
- if cmds == "" then
- cmds = v
- else
- cmds = cmds .. " " .. v
- end
- end
- end
- -- Create our Coroutines
- coGo = coroutine.create(go)
- coFuel = coroutine.create(fuelManager)
- -- Continuously resume coroutines in sequence as they yield
- while true do
- -- Start/Resume our Go coroutine
- yy = coroutine.resume(coGo,cmds)
- if yy == false then
- print("Coroutine Go Reports error")
- print("Status: " .. coroutine.status(coGo))
- end
- -- If the coroutine has terminated, then exit our loop
- if coroutine.status(coGo) == "dead" then
- break
- end
- -- Start/Resume our Fuel coroutine
- yy = coroutine.resume(coFuel)
- if yy == false then
- print("Coroutine Fuel Reports error")
- print("Status: " .. coroutine.status(coFuel))
- end
- -- If the coroutine has terminated, then exit our loop
- if coroutine.status(coFuel) == "dead" then
- print("Out of Fuel")
- break
- end
- end
- return true
- end
- -- Interactive Mode
- function interactiveMode(saveFile)
- term.clear()
- print("Welcome to Interactive Mode")
- print("Instructions enter one command per line, followed by the enter key.")
- print("The turtle will execute the instructions and the instructions will")
- print("be recorded to the file '" .. saveFile .. "'.")
- print("")
- print("Enter the command 'end' to stop")
- print("")
- local fHandler = fs.open(saveFile,"a")
- while true do
- write("Command: ")
- cmd = io.read()
- if go(cmd) then
- if string.lower(cmd) == "end" then
- break
- end
- fHandler.writeLine(cmd)
- end
- end
- fHandler.close()
- end
- -- Checks fuel status on predictable intervals
- function fuelManager()
- local currentFuelLevel = 0
- local avgFuelConsumptionPerSecond = 1
- local estFuelLife = 0
- --- Keep this function active continously
- while true do
- --- Assess current Fuel Level
- currentFuelLevel = turtle.getFuelLevel()
- --- If fuel near Min level, then we need to refuel up to refuel level
- if currentFuelLevel <= fuelMin then
- return false
- end
- --- Calculate approximate time until earliest fuel low warning
- estFuelLife = (currentFuelLevel * avgFuelConsumptionPerSecond)
- --- Sleep for half that time (coroutine should yield here)
- os.sleep(math.floor(estFuelLife/2))
- end -- endless loop
- end
- -- Processes a series of instructions
- function go(cmds)
- local tArgs = { }
- local cmd = ""
- local nPos = 1
- local nCmd = 1
- local c = ""
- -- Convert List of cmds into a table
- while nPos < #cmds do
- c = string.sub(cmds,nPos,nPos)
- if c == " " then
- if cmd ~= "" then
- tArgs[nCmd] = cmd
- cmd = ""
- nCmd = nCmd + 1
- end
- else
- cmd = cmd .. c
- end
- nPos = nPos + 1
- end
- if cmd ~= "" then
- tArgs[nCmd] = cmd
- end
- -- If no commands were found in the table then exit
- if #tArgs < 1 then
- print("No arguments given to go")
- return false
- end
- -- These are our defined handlers. Each handler is defined with a condition and an action.
- -- before an action is executed, a condition must be met
- -- successful actions, will deducated distance values.
- -- Failed conditions or actions will set distance to 0
- local tHandlers = {
- -- Forward, Back, Up, Down
- ["F"] = { condition=function() return true end, action=turtle.forward },
- ["B"] = { condition=function() return true end, action=turtle.back },
- ["U"] = { condition=function() return true end, action=turtle.up },
- ["D"] = { condition=function() return true end, action=turtle.down },
- -- Left, Right
- ["L"] = { condition=function() return true end, action=turtle.turnLeft },
- ["R"] = { condition=function() return true end, action=turtle.turnRight },
- -- Dig Over, Dig uNder
- ["O"] = { condition=turtle.detect, action=turtle.digUp },
- ["N"] = { condition=turtle.detect, action=turtle.digDown },
- -- Plant, Eject
- ["P"] = { condition=function() return not(turtle.detectDown()) end, action=plantSeed },
- ["E"] = { condition=function() return true end, action=dropExtras }
- }
- -- Iterate for each command present
- local nArg = 1
- local sCmd = ""
- for nArg,sCmd in ipairs(tArgs) do
- local nDistance = 1
- -- Determine the Distance for the command
- if #sCmd > 1 then
- local num = tonumber(string.sub(sCmd, 2))
- if num then
- nDistance = num
- else
- nDistance = 1
- end
- else
- nDistance = 1
- end
- sOperation = string.sub(sCmd,1,1)
- -- Use the function handler that corresponds with the command
- local fnHandler = tHandlers[string.upper(sOperation)]
- if fnHandler then
- -- Set our condition and action functions
- local condition = fnHandler["condition"]
- local action = fnHandler["action"]
- -- Repeat based on distance
- while nDistance > 0 do
- local status = false -- whether condition and action both returned true
- if condition() then
- if action() then
- status = true
- end
- else
- status = true
- end
- -- If the action did not succeed, lets check some common reasons
- if status == false then
- -- Out of Fuel?
- if turtle.getFuelLevel() == 0 then
- print( "Out of fuel" )
- return false
- else
- -- Best report his even though it may correct itself in half a second
- print(string.upper(sOperation) .. " returned error")
- sleep(0.5)
- end
- else -- action DID succeed, so lets reduce distance
- nDistance = nDistance - 1
- end
- end -- while distance > 0
- else -- if there was no valid function handler found ...
- print( "No such Handler: " .. string.upper(sOperation) )
- return false
- end
- end -- Process Next Command
- return true
- end
- -- Finds a seed in our inventory and plants it
- -- Should be clear that there needs to be an empty block below in order to properly plant
- function plantSeed()
- local slotNumber = 0
- local itemCount = 0
- local attempt = 0
- local seedItem = false
- for slotNumber=1,16 do
- -- There is a goto command in the new beta Lua .. cannot wait
- local skipIt = false
- while skipIt == false do
- skipIt = true
- if (slotNumber ~= fuelMatchSlot) and (slotNumber ~= seedMatchSlot) then
- -- See if there is any items in the slot
- itemCount = turtle.getItemCount(slotNumber)
- if itemCount == 0 then
- -- goto skipIt
- break
- end
- -- Select the Slot
- while turtle.select(slotNumber) == false do
- attempt = attempt + 1
- if attempt == 3 then
- print("Unable to Select Slot#" .. slotNumber)
- return false
- end
- -- Lets wait - maybe it will clear up
- -- We will only make 3 attemps though
- sleep(5)
- end
- -- Compare it to our seed slot
- seedItem = turtle.compareTo(seedMatchSlot)
- if not seedItem then
- -- goto skipIt
- break
- end
- -- We found a seed item - lets plant it
- if not turtle.placeDown() then
- print("Could not place seed")
- return false
- end
- end -- slot <> seedslot condition
- end -- while
- -- ::skipit::
- end -- next slot number
- return true
- end
- -- Drops all items that are "extra"
- -- at the time of writing, that means anything not fuel or seed
- function dropExtras()
- local slotNumber = 0
- local keepItem = false
- local itemCount = 0
- local attempt = 0
- -- iterate through our slots
- for slotNumber=1,16 do
- -- Can remove these two lines when LUA gets a GOTO statement
- local skipIt = false
- while skipIt == false do
- if (slotNumber ~= fuelMatchSlot) and (slotNumber ~= seedMatchSlot) then
- -- See if there is any items in the slot
- itemCount = turtle.getItemCount(slotNumber)
- if itemCount == 0 then
- -- goto skipIt
- break
- end
- -- Select the Slot, give up after 3 attempts
- while turtle.select(slotNumber) == false do
- attempt = attempt + 1
- if attempt == 3 then
- print("Unable to Select Slot#" .. slotNumber)
- return false
- end
- sleep(5)
- end
- -- Is it an extra?
- keepItem = (turtle.compareTo(fuelMatchSlot) or turtle.compareTo(seedMatchSlot))
- if keepItem then
- -- goto skipIt
- break
- end
- -- We found an extra item - lets drop it
- turtle.dropDown()
- end -- valid slot check
- end -- while loop
- -- :: skipIt ::
- end -- next slot number
- return true
- end
- function reFuel()
- local slotNumber = 0
- local fuelItem = false
- local itemCount = 0
- local attempt = 0
- for slotNumber=1,16 do
- -- Remove these two lines when LUA gets a goto statement
- local skipIt = false
- while skipIt == false do
- skipIt = true
- if not (slotNumber == fuelMatchSlot) then
- -- See if there is any items in the slot
- itemCount = turtle.getItemCount(slotNumber)
- if itemCount == 0 then
- -- goto skipIt
- break
- end
- -- Select the Slot
- while turtle.select(slotNumber) == false do
- attempt = attempt + 1
- if attempt == 3 then
- print("Unable to Select Slot#" .. slotNumber)
- return false
- end
- sleep(5)
- end
- -- Compare it to our fuel slot
- fuelItem = turtle.compareTo(fuelMatchSlot)
- if not fuelItem then
- break
- end
- -- We found a fuel item - lets refuel to the refuel limit
- while turtle.getFuelLevel() < fuelRefill do
- -- Attempt to Refuel with one unit
- attempt = 0
- while turtle.refuel(1) == false do
- attempt = attempt + 1
- if attempt == 1 then
- print("Unable to refuel from slot #" .. slotNumber)
- end
- if attempt == 3 then
- break -- give up on this slot
- end
- os.sleep(1)
- end
- -- If this slot does not appear to refilling then skip the slot
- if attempt == 3 then
- break
- end
- -- Keep refueling until we reach our refill level
- end -- While Refueling
- end -- slot <> fuelslot condition
- -- if we have refueled sufficiently, lets stop checking slots
- if turtle.getFuelLevel() >= fuelRefill then
- break
- end
- end -- end while loop
- end -- next slot number
- -- Return Refuel success
- if turtle.getFuelLevel() < fuelRefill then
- return false
- else
- return true
- end
- end
- local tArgs = { ... }
- main(tArgs)
- print("Finished")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement