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
- function main(cmds)
- local routines = {}
- local eventdata = {}
- local filter = {}
- local status
- local param
- local n
- if #cmds == 1 and fs.exists(cmds[1]) then
- local fileHandler = fs.open(cmds[1],"r")
- if fileHandler then
- local data = fileHandler.readAll()
- cmds = { }
- for k, v in string.gmatch(data,"%a%d+") do
- table.insert(cmds,k)
- end
- end
- fileHandler.close()
- end
- routines[1] = coroutine.create(go)
- routines[2] = coroutine.create(fuelManager)
- routines[3] = coroutine.create(refuel)
- os.queueEvent("fuelCheck")
- os.queueEvent("docmds", unpack(cmds))
- while true do
- for i,r in ipairs(routines) do
- assert(r,"Routine #" .. i .. " does not exist")
- if filter[r] == nil or filter[r] == eventdata[1] or eventdata[1] == "terminate" then
- status, param = coroutine.resume(r, unpack(eventdata))
- assert(status,"Main(): #" .. i .. ", " .. tostring(param))
- filter[r] = param
- if coroutine.status(r) == "dead" then
- print("")
- print("#" .. i .. ": Dead. status=" .. tostring(status) .. ", param=" .. tostring(param))
- if i == 1 then
- return i
- end
- end
- end
- end
- for i,r in ipairs(routines) do
- if coroutine.status(r) == "dead" then
- if i == 1 then
- return i
- end
- end
- end
- eventdata = { coroutine.yield() }
- end
- end
- function go()
- -- Set up our Turtle Handlers
- local TurtleHandlers = {
- -- 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 }
- }
- -- Set up Event Variables
- local EventParams = { }
- repeat
- EventParams = { coroutine.yield("docmds") }
- if EventParams[1] == "terminate" then
- error("Terminated.during.go()", 0)
- end
- until EventParams[1] == "docmds"
- local eventID = EventParams[1]
- table.remove(EventParams,1)
- -- Ensure this is the proper event starting us
- if eventID == "docmds" then
- write("(G)")
- -- For each command, separate it into a command and a distance
- for CommandNumber,CommandFull in ipairs(EventParams) do
- --- Reset our Distance
- local CommandDistanceRemaining = 1
- --- If the command is 2 or more letters long, lets separate the command from the distance
- if #CommandFull > 1 then
- -- Extract from position 2 onwards and convert text to a number
- local tmpNum = tonumber(string.sub(CommandFull,2))
- if tmpNum then
- -- Set our distance value for this command
- CommandDistanceRemaining = tmpNum
- else
- -- there was no distance value, so lets repeat only once
- CommandDistanceRemaining = 1
- end
- --- Extract our Command
- CommandOperation = string.sub(CommandFull,1,1)
- --- Execute our Command
- local FunctionHandler = TurtleHandlers[string.upper(CommandOperation)]
- if FunctionHandler then
- -- Set our condition and action functions
- local condition = FunctionHandler["condition"]
- local action = FunctionHandler["action"]
- -- Repeat based on distance
- while CommandDistanceRemaining > 0 do
- local cResult = condition()
- if cResult and action() and (write(string.upper(CommandOperation))) then
- CommandDistanceRemaining = CommandDistanceRemaining - 1
- else
- if cResult then
- return false
- end
- end
- end -- Distance Countdown
- else
- -- No such Function Handler
- error("No such Turtle Function Handler exists: " .. string.upper(CommandOperation))
- end -- If FunctionHandler
- end -- If 2-char command text
- end -- For every command
- end -- If the event is docmds
- return true
- end
- function fuelManager()
- -- Set up Fuel Variables
- local CFL = 0
- local AFCPS = 1
- local EFL = 0
- --- Set up Event Variables
- local EventParams = { }
- repeat
- EventParams = { coroutine.yield("fuelCheck") }
- if EventParams[1] == "terminate" then
- error("Terminated during fuelManager()",0)
- end
- until EventParams[1] == "fuelCheck"
- local eventID = EventParams[1]
- table.remove(EventParams,1)
- if eventID == "fuelCheck" then
- write("(F)")
- CFL = turtle.getFuelLevel()
- --- Keep going until fuel is near the Min level
- --- then we need to refuel up to refuel level
- while CFL >= fuelMin do
- --- Calculate approximate time until earliest fuel low warning
- local EFL = CFL * AFCPS
- --- Calculate half that time
- EFL = math.floor(EFL / 2)
- -- If our sleep time is less than 5 seconds, lets just exit for a refuel
- if EFL < 5 then
- os.queueEvent("refuel")
- repeat
- eventParams = { coroutine.yield("refueled") }
- if eventParams[1] == "terminate" then
- error("Terminated in WaitForRefuel()")
- end
- until eventParams[1] == "refueled"
- eventID = eventParams[1]
- table.remove(eventParams,1)
- else
- --- Sleep until next scheduled fuel check (coroutine should yield here)
- os.sleep(EFL)
- end
- end
- end
- end
- function refuel()
- -- Set up Local Variables
- local slotNumber = 0
- local fuelItem = false
- local itemCount = 0
- local attempt = 0
- -- Set up Event Variables
- local EventParams = { }
- repeat
- EventParams = os.pullEvent("refuel")
- if EventParams[1] == "terminate" then
- error("Terminated in refuel()")
- end
- until EventParams[1] == "refuel"
- local eventID = EventParams[1]
- table.remove(EventParams,1)
- if eventID == "refuel" then
- write("(R)")
- 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
- print("Exiting Refuel")
- if turtle.getFuelLevel() < fuelRefill then
- return false
- else
- os.queueEvent("refueled")
- return true
- end
- end -- If its our Event
- end
- local targs = { ... }
- local func = ""
- local i = 0
- local func = main(targs)
- if func == 1 then
- print("Commands Completed")
- elseif func == 2 then
- print("Out of Gas")
- elseif func == 3 then
- print("Unable to Refuel")
- else
- print("Not sure what happened ... " .. tostring(func))
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement