Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --experimental untested
- -- The experiments with simulate are failed and should be removed,
- -- or replaced with poz3 experiment
- --theinsektAPIs/poz3a
- --updated version of poz2a
- --it uses poz3, it's a movement api that keeps track of your position
- os.loadAPI("theinsektAPIs/poz3")
- --if simulate is true then returns iters, without doing anything
- function digLoop(direction,iters,refuel,simulate)
- if simulate then return iters end
- direction=poz3.getAbsoluteDirection(direction)
- if(direction==nil) then
- print(
- debug.traceback()
- )
- error("Error: direction is not valid (valid: n,s,w,e,u,d,r,l,f,b)")
- end
- return doLoop(direction,iters,detectDigGo2,refuel)
- end
- --doLoop takes a doFunction as input and runs it iters times
- --doFunction should return true on success and false on fail
- --it takes the direction parameter and an optional parameter as input
- --(the optional parameter could be a table if you want)
- --doLoop turns n,s,w,e,u,d,r,l,f,b into n,s,w,e,u,d
- --doLoop exits immediately if doFunction returns false, and returns the number
- --of successful iterations
- --Use doLoop or use it as an inspiration
- function doLoop(direction,iters,doFunction,optional)
- --check input
- if direction==nil then error("Error: direction is nil") end
- direction=poz3.getAbsoluteDirection(direction)--turn into n,e,s,w,u,d
- if direction==nil then error("Error: unrecognised direction") end
- if doFunction==nil then error("Error: called doLoop with doFunction==nil") end
- if iters<0 then error("Error: iters is negative") end
- --the doLoop
- local i=0
- poz3.turn(direction)--so that it will turn if iters==0
- while( i<iters) do
- if not doFunction(direction,optional) then
- break
- end
- i=i+1
- end
- return i
- end
- function callDigCube(dir1,len1,dir2,len2,dir3,len3,refuel,returnToOrigin)
- --dir1 should not be nil
- if dir1==nil then error("Error: dir1 is nil") end
- dir1=poz3.getAbsoluteDirection(dir1)
- if dir2 ~= nil then
- dir2=poz3.getAbsoluteDirection(dir2)
- end
- if dir3 ~= nil then
- --dir3 should be nil if dir2 is nil
- if(dir2==nil) then error("Error: dir2 can't be nil when dir3 isn't nil") end
- --get absolute direction
- dir3=poz3.getAbsoluteDirection(dir3)
- end
- if not checkNormal(dir1,dir2,dir3) then
- Error("Error: Two direction are on the same line")
- end
- --if a dir is nil then the length should be nil
- if dir2==nil and len2~=nil then error("Error: if dir2 is nil then len2 must be nil") end
- if dir3==nil and len3~=nil then error("Error: if dir3 is nil then len2 must be nil") end
- --nil means default value, and default is 1
- if len1==nil then len1=1 end
- if len2==nil then len2=1 end
- if len3==nil then len3=1 end
- --check that lengths aren't 0 or negative
- if len1<1 then error("Error: all lengths must be larger than 0, len1 isn't") end
- if len2<1 then error("Error: all lengths must be larger than 0, len2 isn't") end
- if len3<1 then error("Error: all lengths must be larger than 0, len3 isn't") end
- --save the origin
- local origin=poz3.getPos2()
- --todo: simulate digCubeHorz and digCubeVert and choose the
- -- fastest with the given values.
- local succes=digCubeHorz(dir1,len1,dir2,len2,dir3,len3,refuel)
- --try to return to origin
- if returnToOrigin then
- if not digToCoords2(origin,refuel) then
- return false
- end
- end
- return succes
- end
- function digCubeHorz(dir1,len1,dir2,len2,dir3,len3,refuel)
- --after optimizing order, dir1 and dir2 will be horizontal and dir3 vertical
- dir1,len1,dir2,len2,dir3,len3=optimizeForHorz(dir1,len1,dir2,len2,dir3,len3)
- --the turtle is inside the cube so need to remove 1 distance
- len1=len1-1
- len2=len2-1
- len3=len3-1
- local ceilingHeight=nil
- local floorHeight=nil
- if dir3=="u" then
- ceilingHeight=poz3.getPosField("y")+len3
- floorHeight=poz3.getPosField("y")
- else
- ceilingHeight=poz3.getPosField("y")
- floorHeight=poz3.getPosField("y")-len3
- end
- --if thicker than 3 then move to more optimal position
- if len3 >= 2 then
- if digLoop(dir3,1,refuel)~=1 then return false end
- len3=len3-1
- end
- local len2backup=len2
- --do the digging
- while(true) do
- while(true) do
- --print("cubeHorz1: ",dir1,":",dir2,":",dir3)
- local height=poz3.getPosField("y")
- local succes1,_=digLoopExtraHorz(dir1,len1,refuel,height~=ceilingHeight,height~=floorHeight)
- if not succes1 then return false end
- dir1=poz3.getReverse(dir1)
- if(len2==0) then break end
- if digLoop(dir2,1,refuel)~=1 then return false end
- len2=len2-1
- end
- len2=len2backup
- dir2=poz3.getReverse(dir2)
- if(len3<=1) then break end --last layer have already been mined
- if(len3-3<0) then
- if digLoop(dir3,2,refuel)~=2 then return false end
- len3=len3-2
- else
- if digLoop(dir3,3,refuel)~=3 then return false end
- len3=len3-3
- end
- end
- return true
- end
- function optimizeForHorz(dir1,len1,dir2,len2,dir3,len3)
- local dirTable={dir1,dir2,dir3}
- local lenTable={len1,len2,len3}
- local verticalDir=3
- local longDir=3
- local shortDir=3
- local longLen=-1
- for index,dir in ipairs(dirTable) do
- if(dir~=nil) then
- if poz3.isVertical(dir) then
- verticalDir=index
- else
- local len=lenTable[index]
- if(len>longLen) then
- if(longLen>-1) then
- --had previous longdir
- --so that should now be shortdir
- shortDir=longDir
- end
- longDir=index
- longLen=len
- else
- shortDir=index
- end
- end
- end
- end--for
- return dirTable[longDir],lenTable[longDir],
- dirTable[shortDir],lenTable[shortDir],
- dirTable[verticalDir],lenTable[verticalDir]
- end
- function detectDig(direction)
- if(poz3.detect(direction)) then
- if(not poz3.dig(direction)) then
- return false
- end
- end
- return true
- end
- function digLoopExtraHorz(direction,length,refuel,up,down)
- if up then up="u" else up=nil end
- if down then down="d" else down=nil end
- --print("loopExtraHorz: ",direction,":",dir1,":",dir2,":",dir3)
- return digLoopExtra(direction,length,refuel,up,down,nil)
- end
- --first return, returns if successful or not
- --second return, returns the number of steps taken
- function digLoopExtra(direction,length,refuel,dir1,dir2,dir3)
- --print("loopExtra: ",direction,":",dir1,":",dir2,":",dir3)
- local i=0
- while(i<length) do
- local succes,len=detectDigGoExtra(direction,refuel,dir1,dir2,dir3,true)
- if not succes then
- return false, i+len
- end
- i=i+1
- end
- return true,i
- end
- --digs and goes in the given direction
- --then in the additional directions
- --have two return values
- --the first is if successful, the second is the number of steps taken
- function detectDigGoExtra(direction,refuel,dir1,dir2,dir3,preDig)
- --print("digExtra: ",direction,":",dir1,":",dir2,":",dir3)
- if preDig then
- if dir1 and not detectDig(dir1) then return false,0 end
- if dir2 and not detectDig(dir2) then return false,0 end
- if dir3 and not detectDig(dir3) then return false,0 end
- end
- if detectDigGo2(direction,refuel) then
- if dir1 and not detectDig(dir1) then return false,1 end
- if dir2 and not detectDig(dir2) then return false,1 end
- if dir3 and not detectDig(dir3) then return false,1 end
- return true,1
- end
- return false,0
- end
- function checkNormal(dir1,dir2,dir3)
- local tmp={}
- return checkNormalHelp(tmp,dir1) and
- checkNormalHelp(tmp,dir2) and
- checkNormalHelp(tmp,dir3)
- end
- function checkNormalHelp(tmp,adir)
- if adir==nil then return true end
- if tmp[adir] or tmp[poz3.getReverse(adir)] then
- return false
- end
- tmp[adir]=adir
- tmp[poz3.getReverse(adir)]=adir
- return true
- end
- function detectDigGo2(direction,refuel)
- --loop so that it won't be stopped by gravel
- while(true) do
- --try to dig if it detects a block
- if(poz3.detect(direction)) then
- if(not poz3.dig(direction)) then
- return false
- end
- end
- --try to go
- if poz3.go(direction) then
- return true
- else
- --if failed because of fuel
- --then refuel if refuel is true
- if turtle.getFuelLevel() == 0 then
- if not refuel or not doRefuel() then
- --refuel was false or had no fuel in inventory
- return false
- end
- end
- os.sleep(0.5)--changed to 0.5 from 1
- end
- end --while
- end
- function digToCoordsHelp(fieldName,targetCoord,refuel)
- local direction, length=poz3.coordToGoValues(fieldName,targetCoord)
- if length==0 then return true,0 end
- local length2=digLoop(direction,length,refuel)
- return length2==length, length2
- end
- function digToCoords(x,y,z,f,refuel)
- local succes=true
- if x~=nil then
- succes = digToCoordsHelp("x",x,refuel) and succes
- end
- if y~=nil then
- succes = digToCoordsHelp("y",y,refuel) and succes
- end
- if z~=nil then
- succes = digToCoordsHelp("z",z,refuel) and succes
- end
- if f~=nil then
- succes = poz3.turn(f) and succes
- end
- return succes
- end
- function digToCoords2(aPosT)
- return digToCoords(aPosT["x"],aPosT["y"],aPosT["z"],aPosT["f"],refuel)
- end
- function doRefuel(amount)
- if amount==nil then
- os.run({},"rom/programs/turtle/refuel")
- --shell.run("refuel")
- else
- --shell.run("refuel",tostring(amount))
- os.run({},"rom/programs/turtle/refuel",tostring(amount))
- end
- return turtle.getFuelLevel()>0
- end
- function refuelToLevel(level)
- local fuelLevel=turtle.getFuelLevel()
- while(fuelLevel<level) do
- doRefuel()
- if(fuelLevel==turtle.getFuelLevel()) then
- return false
- end
- fuelLevel=turtle.getFuelLevel()
- end
- return true
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement