Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --# Turtle Extended API v0.4
- --# Made By Wojbie
- --# http://pastebin.com/X8NEcEVy
- --Rebuild and restructure!
- --split internal and front functions
- --Separate functions into subtables.
- --API Settings - TagControl,DaemonControl
- --Utility ? --making a point ect?
- --work on naming convention
- --cram similiar function into one with some flags.
- --add some kind of map system. - auto save contents of inspection. (Deamon idea? Scan all turtle sees ever so often?)
- --add onScan function()
- --defininf variables for whole api
- --investigame turtle.inventory event for daemon
- --crafting database? use tags for types of wood ect.
- --## ERROR TESTS ##--
- if shell or multishell then
- print("You have run this api instead of loading it. There is no point in doing that. Use os.loadApi to load it.")
- return
- end
- if not turtle then
- error("This is not a turtle. This api will not work outside of the turtle.")
- end
- --## CONSTANTS ##--
- local oldturtle = turtle --Pointing local at global turtle (in case user overwrites it with this api)
- nativeTurtle=oldturtle --acces to basic turtle (in case user overwrites it with this api)
- versionName="TurtleExtended By Wojbie"
- versionNumber=0.4
- --## GLOBALS ##--
- local bMovelock = true --Is true if position of turtle is not set. Stops all movement functions. They will return false.
- local bScanner = false --Automatic scanning to map on movement? Slows movement down.
- local bBrutal = false --Automatic attacking if movement falls
- local bVacuum = false --Automatic vacuum as it moves around
- local pos
- local bInMove = false
- --## SUBTABLES ##--
- util = {}
- tags = {}
- map = {}
- --## RANDOM USEFULL FUCTIONS ##--
- local function save(A,B) local file = fs.open(tostring(A),"w") file.write(B) file.close() end
- local function saveT(A,B) save(A,textutils.serialize(B)) end
- local function saveTL(A,B) save(A,string.gsub(textutils.serialize(B),"\n%s*","")) end
- local function get(A) local file = fs.open(tostring(A),"r") if not file then return false end local data = file.readAll() file.close() if data then return data end end
- local function getT(A) local data = get(A) if data then data = textutils.unserialize(data) end if data then return data end end
- local function getHttp(A) if not http.checkURL(A) then return false end local file = http.get(A) if not file then return false end local data = file.readAll() file.close() if data then return data end end
- local function copyT(...) --Copy table - if more than one merge them - in case of overwriting values last one gets its way
- tArgs={...}
- local B={}
- for _,A in pairs(tArgs) do
- if A and type(A)=="table" then
- for i,k in pairs(A) do
- if type(k)=="table" then B[i]=copyT( B[i] or {},k)
- else B[i]=k end
- end
- end
- end
- return B
- end
- --## TAG DATABASE ##--
- local ProtectedTags={["#All"]=true}
- local tagList={ --#Modname tag is always added by dynamic code
- ["#bedrock"]={{"minecraft:bedrock"},{"factorization:FracturedBedrock"},},
- ["#stone"]={{"minecraft:stone"},},
- ["#cobble"]={{"minecraft:cobblestone"},},
- ["#dirt"]={{"minecraft:dirt",0},{"minecraft:grass"}},
- ["#podzol"]={{"minecraft:dirt",2}},
- ["#sand"]={{"minecraft:sand"},},
- ["#gravel"]={{"minecraft:gravel"},},
- ["#log"]={{"minecraft:log"},{"minecraft:log2"}},
- ["#leaves"]={{"minecraft:leaves"},{"minecraft:leaves2"}},
- ["#tree"]={"#log","#leaves"},
- ["#sapling"]={{"minecraft:sapling"}},
- ["#gravity"]={"#sand","#gravel"},
- ["#liquid"]={{"minecraft:flowing_lava"},{"minecraft:lava"},{"minecraft:flowing_water"},{"minecraft:water"}},
- ["#liquidSourceBlock"]={{"minecraft:flowing_lava",0},{"minecraft:lava",0},{"minecraft:flowing_water",0},{"minecraft:water",0}}, --Thanks to Bomb Bloke for helping me test that!
- ["#containder"]={{"minecraft:chest"},},
- ["#unique"]={{"minecraft:dragon_egg"}},
- ["#ground"]={"#dirt","#stone"},
- ["#ore"]={"#vanillaOre"},
- ["#mineableOre"]={"#vanillaOre"},
- ["#vanillaOre"]={{"minecraft:gold_ore"},{"minecraft:iron_ore"},{"minecraft:coal_ore"},{"minecraft:lapis_ore"},{"minecraft:diamond_ore"},{"minecraft:redstone_ore"},{"minecraft:emerald_ore"},{"minecraft:quartz_ore"}},
- --["#sample"]={{"minecraft:stone"},{"minecraft:lava",1},"#stone"},
- --Blacklist tags
- ["#DigBlacklist"]={"#Blacklist",{"minecraft:mob_spawner"},"#ComputerCraft:","#computercraft:"}, --Spawners are to preacius to mine, Also no canibalism.
- ["#DigWhitelist"]={"#Whitelist",},
- ["#PlaceBlacklist"]={"#Blacklist",{"minecraft:bedrock"}}, --No placing Bedrock on my watch
- ["#PlaceWhitelist"]={"#Whitelist",},
- ["#Blacklist"]={},
- ["#Whitelist"]={},
- --Test tags
- ["#TestAll"]={"#All"},
- ["#TestComputertag"]={"#ComputerCraft:","#computercraft:"},
- }
- local lookupName={}
- --[[{
- ["minecraft:stone"]=
- {
- [true]={["#stone"]=true},
- [3]={["#stone3"]=true},
- [m3]={["#stonem3"]=true},
- [d3]={["#stoned3"]=true},
- }
- }]]--
- local lookupTag={}
- --[[{
- ["#stone"]=
- {
- ["ground"]=true,
- }
- }]]--
- --Database operations
- local function assigntag(tag,list)
- for _,v in pairs(list) do
- if type(v)=="table" then --name meta or just name combo
- if not v[2] then v[2] = true end
- if not lookupName[v[1]] then lookupName[v[1]]={} end
- if not lookupName[v[1]][v[2]] then lookupName[v[1]][v[2]]={} end
- lookupName[v[1]][v[2]][tag]=true
- elseif type(v)=="string" then --tag
- if not lookupTag[v] then lookupTag[v]={} end
- lookupTag[v][tag]=true
- end
- end
- end
- local function removetag(tag,list)
- for _,v in pairs(list) do
- if type(v)=="table" then --name meta or just name combo
- if not v[2] then v[2] = true end
- if not lookupName[v[1]] then lookupName[v[1]]={} end
- if not lookupName[v[1]][v[2]] then lookupName[v[1]][v[2]]={} end
- lookupName[v[1]][v[2]][tag]=nil
- elseif type(v)=="string" then --tag
- if not lookupTag[v] then lookupTag[v]={} end
- lookupTag[v][tag]=nil
- end
- end
- end
- --Filling the database
- for i,k in pairs(tagList) do
- assigntag(i,k)
- end
- --User Accesable functions
- tags.createTag = function(Tag) --Creates new tag
- if tagList[Tag] then return false,"Tag Exists" end
- if ProtectedTags[Tag] then return false,"Tag Protected" end
- tagList[Tag]={}
- return true
- end
- local createTag = tags.createTag
- tags.deleteTag = function(Tag) --Deletes tag and all stuff regeristered to it.
- if not tagList[Tag] then return false,"No such Tag" end
- if ProtectedTags[Tag] then return false,"Tag Protected" end
- removetag(Tag,tagList[Tag])
- tagList[Tag]=nil
- return true
- end
- tags.isTag = function(Tag) --cheacks is tag exists
- return tagList[Tag] and true or false
- end
- local isTag = tags.isTag
- tags.addBlockToTag = function(Tag,Block,Meta)
- if not tagList[Tag] then return false,"No such Tag" end
- if ProtectedTags[Tag] then return false,"Tag Protected" end
- if lookupName[Block] and lookupName[Block][Meta or true] and lookupName[Block][Meta or true][Tag] then return true end
- if not tagList[Tag] then tagList[Tag] = {} end
- table.insert(tagList[Tag],{Block,Meta or true})
- assigntag(Tag,tagList[Tag]) --update lookup tables
- return true
- end
- tags.addSubTagToTag = function(Tag,Child)
- if not tagList[Tag] then return false,"No such Tag" end
- if ProtectedTags[Tag] then return false,"Tag Protected" end
- if not tagList[Tag] then tagList[Tag] = {} end
- if lookupTag[Child] and lookupTag[Child][Tag] then return true end
- table.insert(tagList[Tag],Child)
- assigntag(Tag,tagList[Tag]) --update lookup tables
- return true
- end
- tags.listTag = function(Tag)
- if not tagList[Tag] then return false,"No such Tag" end
- if ProtectedTags[Tag] then return false,"Tag Protected" end
- return copyT(tagList[Tag])
- end
- tags.removeItemFromTag = function(Tag,num)
- if not tagList[Tag] then return false,"No such Tag" end
- if ProtectedTags[Tag] then return false,"Tag Protected" end
- removetag(Tag,tagList[Tag])
- table.remove(tagList[Tag],num)
- assigntag(Tag,tagList[Tag])
- return true
- end
- tags.saveTags = function(A)
- saveT(A or "/tag.log",tagList)
- end
- tags.loadTags = function(A)
- tagList=getT(A or"/tag.log") or {}
- lookupName={}
- lookupTag={}
- for i,k in pairs(tagList) do
- assigntag(i,k)
- end
- end
- tags.loadTagPatch = function(A) --
- patch=getT(A) or {}
- for i,k in pairs(patch) do
- if not isTag(i) then createTag(i) end --if tag don't exists then create it.
- for j,m in pairs(k) do
- table.insert(tagList[i],m) --add new data to tag table
- end
- assigntag(i,k) --populate lookup tables with patch data
- end
- end
- --## MAP DATABASE ##--
- local internamMap = {}
- local metay = {__index=function(f,k) f[k] = {} return f[k] end}--if no y make y and return it (placed on y table)
- local metax = {__index=function(f,k) f[k] = setmetatable({},metay) return f[k] end} --if no x make x and return it (placed on map table)
- setmetatable(internamMap,metax)
- local function cleanMap() --looks trought the map and removes not valid values and empty tables. Cause its eather air or unknown and we don't care about both.
- for kx,vx in pairs(internamMap) do
- for ky,vy in pairs(vx) do
- for kz,vz in pairs(vy) do
- if type(vz)~="table" or (type(vz)=="table" and not next(vz)) then vy[kz]=nil end
- end
- if not next(vy) then vx[ky]=nil end
- end
- if not next(vx) then internamMap[kx]=nil end
- end
- end
- local function setBlock(block,x,y,z) if type(block)=="table" then internamMap[x][y][z] = block return true end end
- local function getBlock(x,y,z) return internamMap[x][y][z] end --add tags in this return
- local function saveMap() end
- local function loadMap() end
- map.setBlock = setBlock
- map.getBlock = getBlock
- map.saveMap = saveMap
- map.loadMap = loadMap
- util.setAutoScan = function(A) bScanner = A and true end
- util.getAutoScan = function() return bScanner and true end
- --## POINT METAMAGIC ##--
- local metaPoint
- metaPoint = {
- __index = {
- copy= function(t) return setmetatable({x=t.x,y=t.y,z=t.z,xd=t.xd,zd=t.zd},metaPoint) end,
- offset = function(t,ox,oy,oz) return t.x and t.y and t.z and setmetatable({x=t.x+ox,y=t.y+oy,z=t.z+oz,xd=t.xd,zd=t.zd},metaPoint) end,
- offsetL = function(t,ox,oy,oz) return t.x and t.y and t.z and t.xd and t.zd and setmetatable({x=t.x+ox*t.xd+oz*-t.zd,y=t.y+oy,z=t.z+oz*t.xd+ox*t.zd,xd=t.xd,zd=t.zd},metaPoint) end,
- offsetP = function(t,A) return t.offset and t:offset(A.x,A.y,A.z) end,
- offsetPL = function(t,A) return t.offsetL and t:offsetL(A.x,A.y,A.z) end, --local to provided point
- ox = function(t,A) return t.offset and t:offset(A or 0,0,0) end,
- oy = function(t,A) return t.offset and t:offset(0,A or 0,0) end,
- oz = function(t,A) return t.offset and t:offset(0,0,A or 0) end,
- up = function(t,A) return t.offset and t:offset(0,(A or 1),0) end,
- down = function(t,A) return t.offset and t:offset(0,-(A or 1),0) end,
- forward = function(t,A) return t.offset and t.xd and t.zd and t:offset((A or 1)*t.xd,0,(A or 1)*t.zd) end,
- back = function(t,A) return t.offset and t.xd and t.zd and t:offset(-(A or 1)*t.xd,0,-(A or 1)*t.zd) end,
- left = function(t,A) return t.offset and t.xd and t.zd and t:offset((A or 1)*t.zd,0,(A or 1)*-t.xd) end,
- right = function(t,A) return t.offset and t.xd and t.zd and t:offset((A or 1)*-t.zd,0,(A or 1)*t.xd) end,
- turnLeft = function(t) return t.offset and t.xd and t.zd and t:offset(0,0,0):setxd(t.zd):setzd(-t.xd) end,
- turnRight = function(t) return t.offset and t.xd and t.zd and t:offset(0,0,0):setxd(-t.zd):setzd(t.xd) end,
- turnBack = function(t) return t.offset and t.xd and t.zd and t:offset(0,0,0):setxd(-t.xd):setzd(-t.zd) end,
- upG = function(t,A) return t.offset and t:offset(0,(A or 1),0) end,
- downG = function(t,A) return t.offset and t:offset(0,-(A or 1),0) end,
- forwardG = function(t,A) return t.offset and pos.xd and pos.zd and t:offset((A or 1)*pos.xd,0,(A or 1)*pos.zd) end,
- backG = function(t,A) return t.offset and pos.xd and pos.zd and t:offset(-(A or 1)*pos.xd,0,-(A or 1)*pos.zd) end,
- leftG = function(t,A) return t.offset and pos.xd and pos.zd and t:offset((A or 1)*pos.zd,0,(A or 1)*-pos.xd) end,
- rightG = function(t,A) return t.offset and pos.xd and pos.zd and t:offset((A or 1)*-pos.zd,0,(A or 1)*pos.xd) end,
- block = function(t) return t.x and t.y and t.z and getBlock(t.x,t.y,t.z) end,
- unp = function(t) return t.x,t.y,t.z,t.xd,t.zd end,
- getf = function(t) if t.xd==0 and t.zd==1 then return 0
- elseif t.xd==-1 and t.zd==0 then return 1
- elseif t.xd==0 and t.zd==-1 then return 2
- elseif t.xd==1 and t.zd==0 then return 3 end end,
- setf = function(t,A) if A==0 then t.xd=0 t.zd=1 return t
- elseif A==1 then t.xd=-1 t.zd=0 return t
- elseif A==2 then t.xd=0 t.zd=-1 return t
- elseif A==3 then t.xd=1 t.zd=0 return t end end,
- setx = function(t,A) t.x=A return t end,
- sety = function(t,A) t.y=A return t end,
- setz = function(t,A) t.z=A return t end,
- setxd = function(t,A) t.xd=A return t end,
- setzd = function(t,A) t.zd=A return t end,
- clearf = function(t,A) t.zd=nil t.xd=nil return t end,
- tos = function(t) return tostring(t) end,
- },
- --__newindex
- --__add
- --__sub
- --__mul
- --__div
- --__mod
- --__pow
- --__unm (-A)
- --__concat
- --__len = Distance for current point to that point in shortest way possible
- --__eq equal = compare coordinates and directions if they are there.
- --__lt larger,smaller --> compare fuel cost on direct route from current pos
- --__le - defaults to not lt so its cool
- --__call
- __tostring = function(t) return "["..(t.x and " x:"..t.x or "")..(t.y and " y:"..t.y or "")..(t.z and " z:"..t.z or "")..(t.xd and " xd:"..t.xd or "")..(t.zd and " zd:"..t.zd or "")..(t.getf and t:getf() and " f:"..t:getf() or "").." ]" end,
- --__metatable
- --# 5.2 up
- --__ipairs
- --__pairs
- --5.3 is ignored for now. lot of bitwise meta added.
- }
- --##DEBUG ITEM
- testpoint = setmetatable({x=0,y=0,z=0,xd=0,zd=1},metaPoint)
- util.makePoint = function(x,y,z,xd,zd) --make a point from coordinates
- return setmetatable({["x"]=x,["y"]=y,["z"]=z,["xd"]=xd,["zd"]=zd},metaPoint)
- end
- util.remakePoint = function(A) --make a point from table
- return setmetatable(A,metaPoint)
- end
- util.savePoint = function(A,B) --save point a into file b
- saveT(B,A)
- end
- metaPoint.__index.save = util.savePoint --add it to point metatable as save
- util.loadPoint = function(A)
- return setmetatable(getT(A or"/gps.log"),metaPoint)
- end
- --## LOCAL POSITION ##--
- pos = setmetatable({x=0,y=0,z=0,xd=1,zd=0},metaPoint) --position of turtle
- --[[savePos = function(A)
- saveT(A or "/gps.log",pos)
- end
- loadPos = function(A)
- pos=setmetatable(getT(A or"/gps.log"),metaPoint) or pos
- end]] --allows bad coding practise. If you realy need it the uncomment it.
- setPos = function(x,y,z,xd,zd) --set position to provided parameters
- pos=setmetatable({["x"]=x,["y"]=y,["z"]=z,["xd"]=xd,["zd"]=zd},metaPoint)
- bMovelock = false
- end
- getPos = function() --get static table with current position
- return setmetatable(copyT(pos),metaPoint)
- end
- --##SEMI-DEBUG ITEM
- getPosDynamic = function() --get table that always contains current position
- return setmetatable({},{__index=pos,__newindex=function() end,__tostring=metaPoint.__tostring})
- end
- --## MOVEMENT CONTROLS ##--
- --##INTERNAL
- local function scan() --scans up forward down
- local status,response,block
- status,response = oldturtle.inspectUp()
- if status then
- block = pos:up():clearf()
- setBlock(response,block:unp())
- end
- status,response = oldturtle.inspect()
- if status then
- block = pos:forward():clearf()
- setBlock(response,block:unp())
- end
- status,response = oldturtle.inspectDown()
- if status then
- block = pos:down():clearf()
- setBlock(response,block:unp())
- end
- end
- local function scanf() --scans just forward
- local status,response,block
- status,response = oldturtle.inspect()
- if status then
- block = pos:forward():clearf()
- setBlock(response,block:unp())
- end
- end
- local function vacuum()
- while turtle.suckUp() do end
- while turtle.suck() do end
- while turtle.suckDown() do end
- end
- turnRight = function(A)
- if bMovelock then return false,"Unknown Position, movement locked" end
- oldturtle.turnRight()
- pos.xd, pos.zd = -pos.zd, pos.xd
- if bScanner or A then scanf() end
- if bVacuum then vacuum() end
- return true
- end
- turnLeft = function(A)
- if bMovelock then return false,"Unknown Position, movement locked" end
- oldturtle.turnLeft()
- pos.xd, pos.zd = pos.zd, -pos.xd
- if bScanner or A then scanf() end
- if bVacuum then vacuum() end
- return true
- end
- up = function(A)
- bInMove = true
- if bMovelock then bInMove = false return false,"Unknown Position, movement locked"
- elseif oldturtle.up() or (bBrutal and oldturtle.attack() and oldturtle.up()) then
- pos.y = pos.y+1
- bInMove = false
- if bScanner or A then scan() end
- if bVacuum then vacuum() end
- return true
- else
- bInMove = false
- return false
- end
- end
- down = function(A)
- bInMove = true
- if bMovelock then bInMove = false return false,"Unknown Position, movement locked"
- elseif oldturtle.down() or (bBrutal and oldturtle.attackDown() and oldturtle.down())then
- pos.y = pos.y-1
- bInMove = false
- if bScanner or A then scan() end
- if bVacuum then vacuum() end
- return true
- else
- bInMove = false
- return false
- end
- end
- forward = function(A)
- bInMove = true
- if bMovelock then bInMove = false return false,"Unknown Position, movement locked"
- elseif oldturtle.forward() or (bBrutal and oldturtle.attack() and oldturtle.forward()) then
- pos.x = pos.x+pos.xd
- pos.z = pos.z+pos.zd
- bInMove = false
- if bScanner or A then scan() end
- if bVacuum then vacuum() end
- return true
- else
- bInMove = false
- return false
- end
- end
- back = function(A)
- bInMove = true
- if bMovelock then bInMove = false return false,"Unknown Position, movement locked"
- elseif oldturtle.back() then
- pos.x = pos.x-pos.xd
- pos.z = pos.z-pos.zd
- bInMove = false
- if bScanner or A then scan() end
- if bVacuum then vacuum() end
- return true
- else
- bInMove = false
- return false
- end
- end
- util.setBrutal = function(A) bBrutal = A and true end
- util.getBrutal = function() return bBrutal and true end
- util.setVacuum = function(A) bVacuum = A and true end
- util.getVacuum = function() return bVacuum and true end
- util.getBrake = function() return bMovelock and true end
- --## GPS LOCATING ##--
- gpsPos=function(A,B) --gets pos from GPS will get lost in process sometimes. -- add movement up and down.
- local pos1,pos2={},{}
- if B then pos1={gps.locate(2,A)} if pos1 then setPos(pos1[1],pos1[2],pos1[3],1,0) bMovelock = true return true end end
- if getFuelLevel()<2 then return false,"Fuel Level Insufficient" end
- pos1={gps.locate(2,A)}
- if not pos1[1] then return false,"No GPS Signal" end
- if pos1[1] and oldturtle.forward() then
- pos2={gps.locate(2,A)}
- if pos2[1] then
- setPos(pos2[1],pos2[2],pos2[3],pos2[1]-pos1[1],pos2[3]-pos1[3])
- back()
- return true
- else
- oldturtle.back()
- return false,"GPS Signal Error"
- end
- elseif pos1[1] and oldturtle.back() then
- pos2={gps.locate(2,A)}
- if pos2[1] then
- setPos(pos2[1],pos2[2],pos2[3],pos1[1]-pos2[1],pos1[3]-pos2[3])
- forward()
- return true
- else
- oldturtle.forward()
- return false,"GPS Signal Error"
- end
- end
- oldturtle.turnLeft()
- if pos1[1] and oldturtle.forward() then
- pos2={gps.locate(2,A)}
- if pos2[1] then
- setPos(pos2[1],pos2[2],pos2[3],pos2[1]-pos1[1],pos2[3]-pos1[3])
- back()
- turnRight()
- return true
- else
- oldturtle.back()
- return false,"GPS Signal Error"
- end
- elseif pos1[1] and oldturtle.back() then
- pos2={gps.locate(2,A)}
- if pos2[1] then
- setPos(pos2[1],pos2[2],pos2[3],pos1[1]-pos2[1],pos1[3]-pos2[3])
- forward()
- turnRight()
- return true
- else
- oldturtle.forward()
- return false,"GPS Signal Error"
- end
- end
- oldturtle.turnRight()
- return false,"Can't move to confirm position"
- end
- --## INSPECT AND GETDETAIL ##--
- local function addtags(t,bDam)
- local tags={}
- local Worklist = copyT(lookupName[t.name] and lookupName[t.name][true],lookupName[t.name] and lookupName[t.name][t.metadata or t.damage],lookupName[t.name] and lookupName[t.name][bDam and "d"..t.damage or "m"..t.metadata]) --merge tags from main block and from metadata/damage subblock and from metadata,damage blocks depending on mode
- local Modtag="#"..string.match(t.name, "^([^:]+:)") --"^([^:]+):"
- Worklist[Modtag]=true
- Worklist["#All"]=true --Utility tag.
- local empty=false
- while not empty do
- empty=true
- for i in pairs(copyT(Worklist)) do --for each tag analize
- empty=false
- Worklist[i]=nil
- tags[i]=true
- Worklist=copyT(Worklist,lookupTag[i]) --add parent tags to WorkList
- end
- end
- t.tags=tags
- return t
- end
- inspect = function()
- local status,response = oldturtle.inspect()
- if status then
- if not bMovelock then
- local block = pos:forward():clearf()
- setBlock(response,block:unp())
- response.point=block
- end
- return status,addtags(response) --scan for m3 type tags -- boollean left as nil
- else
- return status,response
- end
- end
- inspectUp = function()
- local status,response = oldturtle.inspectUp()
- if status then
- if not bMovelock then
- local block = pos:up():clearf()
- setBlock(response,block:unp())
- response.point=block
- end
- return status,addtags(response) --scan for m3 type tags -- boollean left as nil
- else
- return status,response
- end
- end
- inspectDown = function()
- local status,response = oldturtle.inspectDown()
- if status then
- if not bMovelock then
- local block = pos:down():clearf()
- setBlock(response,block:unp())
- response.point=block:clearf()
- end
- return status,addtags(response) --scan for m3 type tags -- boollean left as nil
- else
- return status,response
- end
- end
- getItemDetail = function(A)
- local response = oldturtle.getItemDetail(A)
- if response then
- return addtags(response,true) --scan for d3 type tags
- else
- return response
- end
- end
- --## COMPARE EXPANSION ##--
- local function comp(A,B)
- if A and type(A)=="number" and A>=1 and A<=16 then
- local C=oldturtle.getSelectedSlot()
- oldturtle.select(A)
- local D=B()
- oldturtle.select(C)
- return D
- else
- return B()
- end
- end
- compareSlot = function(A) return comp(A,oldturtle,compare) end
- compareSlotUp = function(A) return comp(A,oldturtle,compareUp) end
- compareSlotDown = function(A) return comp(A,oldturtle,compareDown) end
- compareTwo = function(A,B)
- local C=oldturtle.getSelectedSlot()
- oldturtle.select(A)
- local D=oldturtle,compareTo(B)
- oldturtle.select(C)
- return D
- end
- --## FUEL INFORMATION ##--
- local Fuellimit=term.native().isColor() and 100000 or 20000
- getFuelLevel = function()
- local temp=oldturtle.getFuelLevel()
- return temp=="unlimited" and Fuellimit or temp
- end
- getFuelLimit = function()
- local temp=oldturtle.getFuelLimit()
- return temp=="unlimited" and Fuellimit or temp
- end
- getFuelPercent = function()
- return getFuelLevel()/getFuelLimit()
- end
- getFuelSpace = function()
- return getFuelLimit()-getFuelLevel()
- end
- --## SMART REFUEL ##--
- refuel = function(A) --limit aware refuel
- A = A or 1000
- if A==0 or not oldturtle.refuel(0) then return oldturtle.refuel(0) end
- local current=getFuelLevel()
- local value=0
- if getFuelPercent()<1 then
- oldturtle.refuel(1)
- A=A-1
- value=getFuelLevel()-current
- local toRefuel=math.min(A,math.max(math.ceil(getFuelSpace()/value),0),oldturtle.getItemCount()) --64)
- if toRefuel > 0 then oldturtle.refuel(toRefuel) end
- end
- return true
- end
- --## DIG AND PLACE BLACKLIST/WHITELIST ##--
- ------------------------------------------------------------ADD bScanner block,t = A() setBlock(t.point:unp(),nil)
- local function di(A,B)
- local block,t = A()
- if block then
- --scan for whitelist tag
- if t.tags and t.tags["#DigWhitelist"] then return B() end
- --scan blacklist
- if t.tags and t.tags["#DigBlacklist"] then return false,"Blacklisted" end
- --do it normally
- return B()
- else
- return false,"Nothing to dig here"
- end
- end
- dig = function() return di(inspect,oldturtle.dig) end
- digUp = function() return di(inspectUp,oldturtle.digUp) end
- digDown = function() return di(inspectDown,oldturtle.digDown) end
- ------------------------------------------------------------ADD bScanner block,t = A() setBlock(t.point:unp(),nil)
- local function pi(A,B)
- local t = getItemDetail()
- if t then
- --scan for whitelist tag
- if t.tags and t.tags["#PlaceWhitelist"] then return A(B) end
- --scan blacklist
- if t.tags and t.tags["#PlaceBlacklist"] then return false,"Blacklisted" end
- --do it normally
- return A(B)
- else
- return false,"No items to place"
- end
- end
- place = function(A) return pi(oldturtle.place,A) end
- placeUp = function() return pi(oldturtle.placeUp) end
- placeDown = function() return pi(oldturtle.placeDown) end
- --## PATHFINGING ##--
- --Mode 3/4
- local function upP(A,B,C) --A-Size, B-Scanning, C-Dig
- for i=1,A do
- if up(B) or (C and digUp() and up(B)) then
- return true
- else
- if math.random(0,1)==1 then
- if forward(B) or (C and dig() and forward(B)) or turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then if up(B) or (C and digUp() and up(B)) then return true end end
- else
- if turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) or turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then if up(B) or (C and digUp() and up(B)) then return true end end
- end
- turnLeft(B)
- if math.random(0,1)==1 then
- if forward(B) or (C and dig() and forward(B)) or turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then if up(B) or (C and digUp() and up(B)) then return true end end
- else
- if turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) or turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then if up(B) or (C and digUp() and up(B)) then return true end end
- end
- end
- end
- return false
- end
- local function downP(A,B,C)
- for i=1,A do
- if down(B) or (C and digDown() and down(B)) then
- return true
- else
- if math.random(0,1)==1 then
- if forward(B) or (C and dig() and forward(B)) or turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then if down(B) or (C and digDown() and down(B)) then return true end end
- else
- if turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) or turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then if down(B) or (C and digDown() and down(B)) then return true end end
- end
- turnLeft(B)
- if math.random(0,1)==1 then
- if forward(B) or (C and dig() and forward(B)) or turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then if down(B) or (C and digDown() and down(B)) then return true end end
- else
- if turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) or turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then if down(B) or (C and digDown() and down(B)) then return true end end
- end
- end
- end
- return false
- end
- local function forwardP(A,B,C)
- for i=1,A do
- if forward(B) or (C and dig() and forward(B)) then
- return true
- else
- if math.random(0,1)==1 then
- if up(B) or down(B) or (C and digUp() and up(B)) or (C and digDown() and down(B)) then if forward(B) or (C and dig() and forward(B)) then return true end end
- else
- if down(B) or up(B) or (C and digDown() and down(B)) or (C and digUp() and up(B)) then if forward(B) or (C and dig() and forward(B)) then return true end end
- end
- local dir=math.random(0,1)
- if dir == 1 then turnLeft(B) else turnRight(B) end
- if forward(B) or (C and dig() and forward(B)) then
- if dir == 1 then turnRight(B) else turnLeft(B) end
- if forward(B) or (C and dig() and forward(B)) then return true end
- elseif turnLeft(B) and turnLeft(B) and (forward(B) or (C and dig() and forward(B))) then
- if dir == 1 then turnLeft(B) else turnRight(B) end
- if forward(B) or (C and dig() and forward(B)) then return true end
- end
- end
- end
- return false
- end
- local function backP(A,B,C) --add back pathfinding as forward one with 180 reverse first later
- turnLeft(B)
- turnLeft(B)
- return forwardP(A,B,C)
- end
- --Map based
- --use binary to store blocked directions? Inspect everything
- --if somepalce has only one way in then its 1? that means its blocked.
- --blocked place is like a block you can't break - so in tunnel it would spread until whole tunnel got marked as blocked.
- --instead of going to the place you want to go go 1 block in direction that is not blocked but still leads forard to target.
- --problem - big holes that are blocked - need to figure them out.
- --## GOTO ##--
- local function face(A,B,C)
- if pos.xd==A and pos.zd==B then return end
- if pos.zd==A and -pos.xd==B then turnLeft(C) return end
- if -pos.zd==A and pos.xd==B then turnRight(C) return end
- if -pos.xd==A or -pos.zd==B then turnRight(C) turnRight(C) return end
- end
- util.face = face
- local function fromTo(...) --Distance between 2 points. If given more than 2 points it will claculate minimal fuel to go from first to last in order given
- local tArgs={...}
- if #tArgs==1 then return 0
- elseif #tArgs==2 then return math.abs((tArgs[1].x-tArgs[2].x)) + math.abs((tArgs[1].y-tArgs[2].y)) + math.abs((tArgs[1].z-tArgs[2].z))
- else return fromTo(tArgs[1],tArgs[2])+fromTo(unpack(tArgs,2)) end
- end
- util.fromTo = fromTo
- metaPoint.__index.fromTo = fromTo
- local function fromTo2d(...) --Distance between 2 points. If given more than 2 points it will claculate minimal fuel to go from first to last in order given. Ignores height.
- local tArgs={...}
- if #tArgs==1 then return 0
- elseif #tArgs==2 then return math.abs((tArgs[1].x-tArgs[2].x)) + math.abs((tArgs[1].z-tArgs[2].z))
- else return fromTo2d(tArgs[1],tArgs[2])+fromTo2d(unpack(tArgs,2)) end
- end
- util.fromTo2d = fromTo2d
- metaPoint.__index.fromTo2d = fromTo2d
- local moves = {} --1 goto, 2 goto + mine obscales, 3 goto + pathfind1, 4 goto + mine obscales then pathfind1 if mine failed, 5 - planned - goto + pathfind then mine if pathfind failed.
- moves[1] = {
- ["up"] = function(C,D) return up(D) end,
- ["forward"] = function(C,D) return forward(D) end,
- ["down"] = function(C,D) return down(D) end,
- }
- moves[2] = {
- ["up"] = function(C,D) if not up(D) then return digUp() else return true end end,
- ["forward"] = function(C,D) if not forward(D) then return dig() else return true end end,
- ["down"] = function(C,D) if not down(D) then return digDown() else return true end end,
- }
- moves[3] = {
- ["up"] = function(C,D) return upP(C,D) end,
- ["forward"] = function(C,D) return forwardP(C,D) end,
- ["down"] = function(C,D) return downP(C,D) end,
- }
- moves[4] ={ --make upPD downPD forwardPD backPD
- ["up"] = function(C,D) if not up(D) then digUp() return upP(C,D,true) else return true end end,
- ["forward"] = function(C,D) if not forward() then dig() return forwardP(C,D,true) else return true end end,
- ["down"] = function(C,D) if not down(D) then digDown() return downP(C,D,true) else return true end end,
- }
- local function BlackTest() -- tests if block you are going to is blacklisted.
- end
- goto = function(A,B,C,D) --A target point, B move mode, C used only for pathfinding - defines how far turtle will move from start point, D Force scanning for duration of goto.
- if A and type(A) == "table" and A.x and A.y and A.z and type(A.x)== "number" and type(A.y)== "number" and type(A.z)== "number" then
- B=B or 1 --B=1 is default if B not defined
- C=C or 5 --C=5 is default if C not defined
- D = true
- local move = moves[B]
- if not move then
- error("Illegal movement mode selected.",1)
- end
- while A.x-pos.x ~= 0 or A.y-pos.y ~= 0 or A.z-pos.z ~= 0 do
- if getFuelLevel()<fromTo(A,pos) then return false,"Fuel Level Insufficient" end
- --going up always takes priority
- if A.y-pos.y > 0 then while A.y-pos.y ~= 0 do if not move.up(C,D) then break end end end
- if A.x-pos.x < 0 then face(-1,0) while A.x-pos.x ~= 0 and pos.xd==-1 and pos.zd==0 do if not move.forward(C,D) then break end end end
- if A.x-pos.x > 0 then face(1,0) while A.x-pos.x ~= 0 and pos.xd==1 and pos.zd==0 do if not move.forward(C,D) then break end end end
- if A.z-pos.z < 0 then face(0,-1) while A.z-pos.z ~= 0 and pos.xd==0 and pos.zd==-1 do if not move.forward(C,D) then break end end end
- if A.z-pos.z > 0 then face(0,1) while A.z-pos.z ~= 0 and pos.xd==0 and pos.zd==1 do if not move.forward(C,D) then break end end end
- if A.y-pos.y < 0 then while A.y-pos.y ~= 0 do if not move.down(C,D) then break end end end
- sleep(0.05)
- end
- else
- return false,"Invalid point"
- end
- if A.xd and A.zd then
- face(A.xd,A.zd)
- end
- return true
- end
- metaPoint.__index.goto = goto
- --## Daemon ##--
- --Only if _WojbieStarter = true
- if _WojbieStarter then
- local bRunning = false
- local bOn = false
- local nCur = false
- runDaemon = function(apiName,apiTable) --deamon version for custom coorutine menager. Works like rednet.run
- if bRunning then
- error( "Daemon is already running", 2 )
- end
- bRunning = true
- --load patches from .tPatch/
- if fs.exists("/.tPatch") and fs.isDir("/.tPatch") then
- for i,k in pairs(fs.list("/.tPatch")) do
- tags.loadTagPatch(fs.combine("/.tPatch",k))
- end
- end
- --Modem watchdog - ensures that gps chanel is always open.
- local sModemSide = nil
- local function testModem() -- Find a modem
- if sModemSide and peripheral.getType( sModemSide ) == "modem" and peripheral.call( sModemSide, "isWireless" ) and peripheral.call( sModemSide, "isOpen" , gps.CHANNEL_GPS) then
- return true
- end
- sModemSide = nil
- for n,sSide in ipairs( rs.getSides() ) do
- if peripheral.getType( sSide ) == "modem" and peripheral.call( sSide, "isWireless" ) then
- local ok = pcall(peripheral.call,sSide, "open" , gps.CHANNEL_GPS) --overdrawing on channels test.
- if ok then sModemSide = sSide break end
- end
- end
- return sModemSide and true
- end
- -- Open a channel
- --Main daemon part - GPS host and fuel labeler.
- local tEvents
- local timer = os.startTimer(1)
- while true do
- tEvents={os.pullEventRaw()}
- --Gps responding
- --"modem_message" Side Channel ReplyChannel Message Distance
- if bOn and (not bInMove) and tEvents[1] == "modem_message" and testModem() and tEvents[2] == sModemSide and tEvents[3] == gps.CHANNEL_GPS and tEvents[5] == "PING" then
- peripheral.call( sModemSide, "transmit", tEvents[4] , gps.CHANNEL_GPS, { pos.x, pos.y, pos.z } )
- --Local turtle menagement.
- --"timer nTimer
- elseif tEvents[1] == "timer" and tEvents[2] == timer then
- timer = os.startTimer(1)
- --Retesting modem.
- if bOn then testModem() end
- --Retesting fuel label.
- if nCur and os.getComputerLabel() and nCur ~= getFuelPercent() then os.setComputerLabel((string.match(os.getComputerLabel(),"^(.+) %[[%d%.]-%%%]$") or os.getComputerLabel()).." ["..(math.floor(turtle.getFuelPercent()*1000)/10).."%]") nCur = getFuelPercent() end end
- end
- end
- util.setDaemonGps = function(A) bOn = A and true end
- util.getDaemonGps = function() return bOn and true end
- util.setFuelLabel = function(A) if A and os.getComputerLabel() then nCur = -1 elseif os.getComputerLabel() then os.setComputerLabel(string.match(os.getComputerLabel(),"^(.+) %[[%d%.]-%%%]$") or os.getComputerLabel()) nCur = false end end
- util.getFuelLabel = function() return nCur and true end
- end
- --## PERIPHERAL FIXER ##--
- util.peripheralFix = function()
- --Detect
- --Fix
- --End
- end
- --## TURTLE FUNCTIONS DUPLICATOR ##--
- --in case this api is loaded onto turtle api.
- local env = _ENV
- for k,v in pairs( oldturtle ) do
- if not rawget(env, k) then env[k] = v end -- place the value defined before or use oldturtle one
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement