Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Flow turtle library
- -- By Sxw1212
- local data = { pos = {}, map = {}, waypoints = {}, mapping = true, advmapping = false }
- function load()
- if fs.exists("/.flow.dat") then
- local fh = fs.open("/.flow.dat", "r")
- if fh then
- data = textutils.unserialize(fh.readAll())
- fh.close()
- else
- print("Error loading data file")
- end
- end
- if data.pos == {} then
- print("Set position with setPos(x, y, z, f)")
- end
- end
- function save()
- fs.delete("/.flow.dat")
- local fh = fs.open("/.flow.dat", "w")
- if fh then
- fh.write(textutils.serialize(data))
- fh.close()
- else
- print("Error saving")
- end
- end
- function setMapping(mapping)
- data.mapping = mapping
- save()
- end
- function setAdvMapping(advmapping)
- data.advmapping = advmapping
- save()
- end
- function setPos(x, y, z, f)
- data.pos = {x, y, z, f}
- save()
- end
- function finc()
- if data.pos[4] == 0 then
- data.pos[3] = data.pos[3] + 1
- elseif data.pos[4] == 1 then
- data.pos[1] = data.pos[1] - 1
- elseif data.pos[4] == 2 then
- data.pos[3] = data.pos[3] - 1
- elseif data.pos[4] == 3 then
- data.pos[1] = data.pos[1] + 1
- end
- save()
- end
- function binc()
- if data.pos[4] == 0 then
- data.pos[3] = data.pos[3] - 1
- elseif data.pos[4] == 1 then
- data.pos[1] = data.pos[1] + 1
- elseif data.pos[4] == 2 then
- data.pos[3] = data.pos[3] + 1
- elseif data.pos[4] == 3 then
- data.pos[1] = data.pos[1] - 1
- end
- save()
- end
- function linc()
- if data.pos[4] == 0 then
- data.pos[4] = 3
- else
- data.pos[4] = data.pos[4] - 1
- end
- save()
- end
- function rinc()
- if data.pos[4] == 3 then
- data.pos[4] = 0
- else
- data.pos[4] = data.pos[4] + 1
- end
- save()
- end
- function initpos(x, y, z)
- if not data.map[x] then
- data.map[x] = {}
- end
- if not data.map[x][y] then
- data.map[x][y] = {}
- end
- if not data.map[x][y][z] then
- data.map[x][y][z] = false
- end
- end
- function incf()
- local f = data.pos[4]
- if f == 0 then
- return data.pos[1], data.pos[3] + 1
- elseif f == 1 then
- return data.pos[1] - 1, data.pos[3]
- elseif f == 2 then
- return data.pos[1], data.pos[3] - 1
- elseif f == 3 then
- return data.pos[1] + 1, data.pos[3]
- end
- end
- function advmap()
- if data.advmapping then
- local x = data.pos[1]
- local y = data.pos[2]
- local z = data.pos[3]
- local f = data.pos[4]
- turnLeft()
- map(true)
- turnRight()
- turnRight()
- map(true)
- turnLeft()
- end
- end
- function map(recurse)
- if data.mapping then
- local x = data.pos[1]
- local y = data.pos[2]
- local z = data.pos[3]
- local f = data.pos[4]
- initpos(x, y, z)
- data.map[x][y][z] = false
- initpos(x, y + 1, z)
- if turtle.detectUp() then
- data.map[x][y+1][z] = true
- end
- initpos(x, y - 1, z)
- if turtle.detectDown() then
- data.map[x][y-1][z] = true
- end
- x, z = incf()
- initpos(x, y, z)
- if turtle.detect() then
- data.map[x][y][z] = true
- end
- if not recurse then
- advmap()
- end
- save()
- end
- end
- function getPos()
- return data.pos
- end
- -- Basic turtle movement
- local oldturtle = {}
- for k, v in pairs(turtle) do
- oldturtle[k] = v
- end
- function forward()
- if oldturtle.forward() then
- finc()
- map()
- return true
- else
- return false
- end
- end
- function back()
- if oldturtle.back() then
- binc()
- map()
- return true
- else
- return false
- end
- end
- function up()
- if oldturtle.up() then
- data.pos[2] = data.pos[2] + 1
- map()
- return true
- else
- return false
- end
- end
- function down()
- if oldturtle.down() then
- data.pos[2] = data.pos[2] - 1
- map()
- return true
- else
- return false
- end
- end
- function turnLeft()
- oldturtle.turnLeft()
- linc()
- return true
- end
- function turnRight()
- oldturtle.turnRight()
- rinc()
- return true
- end
- turtle.up = up
- turtle.down = down
- turtle.turnLeft = turnLeft
- turtle.turnRight = turnRight
- turtle.forward = forward
- turtle.back = back
- -- More advanced movement
- function face(f, recurse)
- if data.pos[4] == f then
- return true
- end
- local turn = data.pos[4] - f
- if turn == -1 or turn == 3 then
- turnRight()
- elseif turn == 1 or 3 then
- turnLeft()
- elseif math.abs(turn) == 2 then
- turnLeft()
- turnLeft()
- end
- if not recurse then
- face(f, true)
- end
- return true
- end
- turtle.face = face
- -- Oh my god I hate pathfinding, but I need it xD
- -- Nomap is optional, don't use it unless you KNOW there is a path, and even then... :P
- -- TL;DR: Dont use it.
- function pathfind(x, y, z, nomap, recurse)
- local function cost(x, y, z)
- if data.map[x] then
- if data.map[x][y] then
- -- I use == false because it's unknown
- if data.map[x][y][z] then
- return nil
- elseif data.map[x][y][z] == false then
- return 1
- end
- end
- end
- return nomap
- end
- local path = Pathfinder.findPath3D(cost, data.pos[1], data.pos[2], data.pos[3], x, y, z)
- if path then
- while path do
- local curDir = data.pos[4]
- if path.position.x > data.pos[1] then
- curDir = 3
- elseif path.position.x < data.pos[1] then
- curDir = 1
- elseif path.position.z > data.pos[3] then
- curDir = 0
- elseif path.position.z < data.pos[3] then
- curDir = 2
- end
- face(curDir)
- if data.pos[2] < path.position.y then
- up()
- elseif data.pos[2] > path.position.y then
- down()
- elseif data.pos[1] ~= path.position.x or data.pos[3] ~= path.position.z then
- forward()
- end
- path = path.next
- end
- if not recurse then
- local done = true
- if x ~= data.pos[1] then
- done = false
- elseif y ~= data.pos[2] then
- done = false
- elseif z ~= data.pos[3] then
- done = false
- end
- if not done then
- -- In case of minor changes
- pathfind(x, y, z, nomap, true)
- end
- end
- return true
- else
- return false
- end
- end
- function setWaypoint(name, x, y, z)
- x = x or data.pos[1]
- y = y or data.pos[2]
- z = z or data.pos[3]
- data.waypoints[name] = {x, y, z}
- save()
- end
- function gotoWaypoint(name)
- if data.waypoints[name] then
- return pathfind(data.waypoints[name][1], data.waypoints[name][2], data.waypoints[name][3])
- end
- return false
- end
- function delWaypoint(name)
- data.waypoints[name] = nil
- save()
- end
- function getWaypoints(name)
- return data.waypoints
- end
- function reset(sure)
- if sure then
- data.waypoints = {}
- data.map = {}
- save()
- return true
- else
- return false
- end
- end
- -- Misc
- function wander(moves)
- for i = 1, moves do
- local move = math.floor(math.random()*5)
- if move == 0 then
- forward()
- elseif move == 1 then
- back()
- elseif move == 2 then
- turnLeft()
- elseif move == 3 then
- up()
- elseif move == 4 then
- down()
- end
- end
- end
- load()
- function update(file)
- file = file or "/flow"
- local url = "https://raw.github.com/Sxw1212/ccprograms/master/flow"
- local req = http.get(url)
- if req then
- local fh = fs.open(file, "w")
- fh.write(req.readAll())
- fh.close()
- return true
- else
- return false
- end
- end
- -- All credit goes to TehPers on the pathfinder API
- if not fs.exists("/.pf/flow") then
- fs.makeDir("/.pf")
- local burl = "https://raw.github.com/Sxw1212/ccprograms/master/TehPers/Pathfinder/"
- local files = { "MinHeap", "Pathfinder", "deepcopy", "Point", "SearchNode", "Surr" }
- for k, v in pairs(files) do
- local req = http.get(burl .. v)
- if req then
- local fh = fs.open("/.pf/" ..v, "w")
- fh.write(req.readAll())
- fh.close()
- else
- error("Error loading Pathfinder")
- end
- end
- fs.makeDir("/.pf/flow")
- end
- os.loadAPI("/.pf/Pathfinder")
- os.loadAPI("/.pf/Point")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement