Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --start by localizing everything
- local shell, term, turtle, gps, fs, unpack, pairs, next, getfenv, tonumber, print, tFile = shell, term, turtle, gps, fs, unpack, pairs, next, getfenv, tonumber, print
- --(but HD thats pointless) dont argue I am weird like that
- if not turtle then --why are we even here?
- error("Not a turtle")
- end
- local function pastebin(sName, sFile) --Gets pastebin files
- tPaste = http.get("http://www.pastebin.com/raw/"..sName)
- if not fs.exists(sFile) then
- local tInternal = fs.open(sFile,"w")
- for line in tPaste.readLine do
- tInternal.writeLine(line)
- end
- tInternal.close()
- end
- end
- --some creative table look up
- local tFacing = {
- north={sLeft="west",sRight="east",sBack="south",sForward="z",iMulti=-1},
- east={sLeft="north",sRight="south",sBack="west",sForward="x",iMulti=1},
- south={sLeft="east",sRight="west",sBack="north",sForward="z",iMulti=1},
- west={sLeft="south",sRight="north",sBack="east",sForward="x",iMulti=-1},
- up={sForward="y",iMulti=1},
- down={sForward="y",iMulti=-1}
- }
- local function fGetInventory() --get the turtles inventory currently
- local tOutput = {}
- for i=1,16 do
- tOutput[i] = turtle.getItemDetail(i)
- end
- return tOutput
- end
- if not fs.isDir(".tortoise") then --make the data table if we have never run this turtle before
- fs.makeDir(".tortoise/apis")
- pastebin("0zvqEG6N",".tortoise/apis/daemon")
- for i=1,16 do --find an empty slot
- if turtle.getItemCount(i)==0 then
- turtle.select(i)
- break
- end
- if i==16 then --no empty slot? make one
- turtle.select(i)
- turtle.dropUp()
- end
- end
- local X,y,Z,sFacing
- local equipLeft,equipRight
- turtle.equipLeft()
- local equipLeft = turtle.getItemDetail() --what is in our left hand?
- turtle.equipLeft()
- turtle.equipRight()
- local equipRight = turtle.getItemDetail() --what is in our right hand?
- turtle.equipRight()
- turtle.suckUp() --if we dropped an item earlier lets try to pick it up
- local iX, iY, iZ = gps.locate(2) --if we have a gps may as well double check our position
- if iX then
- local iRot = 0
- while not turtle.forward() do --attempt to move forward
- if not turtle.detect() and not turtle.attack() then --if there isnt a block or mob
- turtle.refuel()
- else
- turtle.turnLeft()
- iRot = iRot + 1
- end
- end
- local iNewX,iNewY,iNewZ = gps.locate(2) --where are we now?
- sFacing = ({[-1]={[0]="west"},[0]={[-1]="north",[1]="south"},[1]={[0]="east"}})[iNewX-iX][iNewZ-iZ] --determine our direction
- if not turtle.back() then
- iX,iZ=iNewX,iNewZ --if we couldnt go back go ahead and make this the new position and stay
- end
- for i=1,iRot%4 do
- turtle.turnRight()
- sFacing = tFacing[sFacing].sRight
- end
- X,Y,Z = iX,iY,iZ
- else
- print("This will only happen once")
- print("Pos: ")
- write(" X: ")
- X = tonumber(read())
- write(" Y: ")
- Y = tonumber(read())
- write(" Z: ")
- Z = tonumber(read())
- write("Facing: ")
- sFacing = read()
- print("Thank you!\nIf this disrupted anything please just reboot the turtle\nWe shouldn't ask any of this again.")
- end
- tFile = fs.open(".tortoise/data","w")
- local tData = {
- tPosition = {x=X,y=Y,z=Z},
- sFacing = sFacing,
- tEquipment = {tLeft=equipLeft,tRight=equipRight},
- tInventory = fGetInventory(),
- iFuel = turtle.getFuelLevel(),
- sMove = "none",
- tLog = {},
- }
- tFile.write(textutils.serialize(tData):gsub("\10",""))
- tFile.close()
- end
- if not daemon then
- os.loadAPI(".tortoise/apis/daemon") --this is used for inventory updating and async turtle functions
- end
- local function tblHandle(tbl,key) --for the multi dimensional tables in turtle data
- return {
- __newindex = function(t,k,v)
- rawset(t.handle,k,v)
- tbl[key] = t.handle
- end;
- __index = function(t,k)
- if type(t.handle[k])=="table" then
- return setmetatable({handle=t.handle[k]},tblHandle(t,k))
- end
- return t.handle[k]
- end;
- }
- end
- local tInternalMeta = { --meta data for our internal stores
- __newindex = function(t,k,v)
- rawset(t.handle,k,v)
- tFile = fs.open(".tortoise/data","w")
- tFile.write(textutils.serialize(t.handle):gsub("\10",""))
- tFile.close()
- end;
- __index = function(t,k)
- if type(rawget(t.handle,k))=="table" then
- return setmetatable({handle=rawget(t.handle,k)},tblHandle(t,k)) --tables are hard
- else
- return rawget(t.handle,k)
- end
- end;
- }
- tFile = fs.open(".tortoise/data","r")
- local tTurtleData = setmetatable({handle=textutils.unserialize(tFile.readLine())},tInternalMeta)--this will handle saving and loading for us automatically
- tFile.close()
- local function fUpdateInventory()
- while true do
- os.pullEventRaw()
- tTurtleData.tInventory = fGetInventory()
- end
- end
- daemon.add(fUpdateInventory,"tortoise inventory management")
- local tLog = tTurtleData.tLog
- local iX, iY, iZ = gps.locate(2) --if we have a gps may as well double check our position
- if iX then
- local iRot = 0
- tPos = turtle.tPosition
- if tPos and (tPos.x~=iX or tPos.y~=iY or tPos.z~=iZ) then
- while not turtle.forward() do --attempt to move forward
- if not turtle.detect() and not turtle.attack() then --if there isnt a block or mob
- turtle.refuel()
- else
- turtle.turnLeft()
- iRot = iRot + 1
- end
- end
- local iNewX,iNewY,iNewZ = gps.locate(2) --where are we now?
- tTurtleData.sFacing = ({[-1]={[0]="north"},[0]={[-1]="west",[1]="east"},[1]={[0]="south"}})[iX-iNewX][iZ-iNewZ] --determine our direction
- if not turtle.back() then
- iX,iZ=iNewX,iNewZ --if we couldnt go back go ahead and make this the new position and stay
- end
- for i=1,iRot%4 do
- tTurtleData.sFacing = tFacing[tTurtleData.sFacing].sRight
- turtle.turnRight()
- end
- end
- tTurtleData.tPosition = {x=iX,y=iY,z=iZ}
- end
- function updatePosition() --if we moved find out where
- if tTurtleData.sMove~="none" then
- local tInternalFace = tFacing[tTurtleData.sMove] --this is our current direction
- tTurtleData.tPosition[tInternalFace.sForward] = tTurtleData.tPosition[tInternalFace.sForward] + (tInternalFace.iMulti * (tTurtleData.iFuel - turtle.getFuelLevel())) --fancy math determines where we are now in one equation
- tTurtleData.iFuel = turtle.getFuelLevel() --get new fuel level
- end
- end
- function forward(iNum) --try to move forward
- iNum = iNum or 1
- local bValid
- if iNum > tTurtleData.iFuel then
- return false
- end
- if tTurtleData.sMove~=tTurtleData.sFacing then --if we have turned lets find out where we are first
- updatePosition()
- tTurtleData.sMove=tTurtleData.sFacing
- end
- local iEnd
- for i=1,iNum do
- bValid = turtle.forward()
- if not bValid then
- iEnd = i - 1
- break
- else
- tLog[#tLog.handle+1] = "back"
- end
- end
- return bValid, iEnd --return what happened
- end
- function back(iNum) --try to move back
- iNum = iNum or 1
- local bValid
- if iNum > tTurtleData.iFuel then
- return false
- end
- if tTurtleData.sMove~=tFacing[tTurtleData.sFacing].sBack then --is the last movement opposite of our current facing?
- updatePosition()
- tTurtleData.sMove=tFacing[tTurtleData.sFacing].sBack
- end
- local iEnd
- for i=1,iNum do
- bValid = turtle.back()
- if not bValid then
- iEnd = i - 1
- break
- else
- tLog[#tLog.handle+1] = "forward"
- end
- end
- return bValid, iEnd --return what happened
- end
- function up(iNum) --try to go up
- iNum = iNum or 1
- local bValid
- if iNum > tTurtleData.iFuel then
- return false
- end
- if tTurtleData.sMove~="up" then --did we move up earlier?
- updatePosition()
- tTurtleData.sMove="up"
- end
- local iEnd
- for i=1,iNum do
- bValid = turtle.up()
- if not bValid then
- iEnd = i - 1
- break
- else
- tLog[#tLog.handle+1] = "down"
- end
- end
- return bValid, iEnd --return what happened
- end
- function down(iNum) --same comments for up..in reverse
- iNum = iNum or 1
- local bValid
- if iNum > tTurtleData.iFuel then
- return false
- end
- if tTurtleData.sMove~="down" then
- updatePosition()
- tTurtleData.sMove="down"
- end
- local iEnd
- for i=1,iNum do
- bValid = turtle.down()
- if not bValid then
- iEnd = i - 1
- break
- else
- tLog[#tLog.handle+1] = "up"
- end
- end
- return bValid, iEnd --return what happened
- end
- function turnLeft() --try to turn left
- tTurtleData.sFacing = tFacing[tTurtleData.sFacing].sLeft --get the facing left of our current
- tLog[#tLog.handle+1] = "turnRight"
- return turtle.turnLeft()
- end
- function turnRight() --same as above but in reverse
- tTurtleData.sFacing = tFacing[tTurtleData.sFacing].sRight
- tLog[#tLog.handle+1] = "turnLeft"
- return turtle.turnRight()
- end
- function strafeLeft(iNum)
- turnLeft()
- local bValid, iEnd = forward(iNum)
- turnRight()
- return bValid, iEnd
- end
- function strafeRight(iNum)
- turnRight()
- local bValid, iEnd = forward(iNum)
- turnLeft()
- return bValid, iEnd
- end
- function reverse()
- tTurtleData.sFacing = tFacing[tTurtleData.sFacing].sBack --get the opposite
- turtle.turnLeft()
- tLog[#tLog.handle+1] = "reverse"
- return turtle.turnLeft()
- end
- function equipLeft(iSlot,iDamage) --try to equip a new item on the left
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- local tItem = turtle.getItemDetail() --if it works what would this item be?
- if turtle.equipLeft() then --now lets equip
- tTurtleData.tEquipment.tLeft = tItem--if it equipped then we know what it now is
- return true
- end
- return false --if we got here we couldnt equip
- end
- function equipRight(iSlot, iDamage) --same as above but for the right side
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- local tItem = turtle.getItemDetail()
- if turtle.equipRight() then
- tTurtleData.tEquipment.tRight = tItem
- return true
- end
- return false
- end
- function select(iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- return turtle.select(iSlot)
- end
- function getItemCount(iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- return iSlot and turtle.getItemCount(iSlot) or turtle.getItemCount()
- end
- function getItemSpace(iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- return iSlot and turtle.getItemSpace(iSlot) or turtle.getItemSpace()
- end
- function suck(iCount,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return iCount and turtle.suck(iCount) or turtle.suck()
- end
- function suckUp(iCount,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return iCount and turtle.suckUp(iCount) or turtle.suckUp()
- end
- function suckDown(iCount,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return iCount and turtle.suckDown(iCount) or turtle.suckDown()
- end
- function drop(iCount,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return iCount and turtle.drop(iCount) or turtle.drop()
- end
- function dropUp(iCount,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return iCount and turtle.dropUp(iCount) or turtle.dropUp()
- end
- function dropDown(iCount,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return iCount and turtle.dropDown(iCount) or turtle.dropDown()
- end
- function place(sText,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return sText and turtle.place(sText) or turtle.place()
- end
- function placeUp(sText,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return sText and turtle.placeUp(sText) or turtle.placeUp()
- end
- function placeDown(sText,iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- return sText and turtle.placeDown(sText) or turtle.placeDown()
- end
- function compareTo(iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- return turtle.CompareTo(iSlot)
- end
- function compareUpTo(iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- local iCurr = turtle.getSelectedSlot()
- turtle.select(iSlot)
- local bResult = turtle.compareUp()
- turtle.select(iCurr)
- return bResult
- end
- function compareDownTo(iSlot, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- local iCurr = turtle.getSelectedSlot()
- turtle.select(iSlot)
- local bResult = turtle.compareDown()
- turtle.select(iCurr)
- return bResult
- end
- function has(sName)
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==sName then
- return i
- end
- end
- return false
- end
- function transferTo(iSlot,iQuantity, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- return iQuantity and turtle.transferTo(iSlot,iQuantity) or turtle.transferTo(iSlot)
- end
- function transferFrom(iSlot,iQuantity, iDamage)
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- local iCurr = turtle.getSelectedSlot()
- turtle.select(iSlot)
- if iQuantity then
- turtle.transferTo(iCurr,iQuantity)
- else
- turtle.transferTo(iCurr)
- end
- turtle.select(iCurr)
- end
- function transferBetween(iFrom,iTo,iQuantity, iDamageTo, iDamageFrom)
- if type(iFrom)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iFrom and (not iDamage or tTurtleData.tInventory[i].damage==iDamageFrom) then
- iFrom = i
- break
- elseif not tTurtleData.tInventory[i] and iFrom=="empty" then
- iFrom = i
- break
- end
- end
- end
- if type(iFrom)=="string" then
- return false
- end
- if type(iTo)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iTo and (not iDamage or tTurtleData.tInventory[i].damage==iDamageTo) then
- iTo = i
- break
- elseif not tTurtleData.tInventory[i] and iTo=="empty" then
- iTo = i
- break
- end
- end
- end
- if type(iTo)=="string" then
- return false
- end
- local iCurr = turtle.getSelectedSlot()
- turtle.select(iFrom)
- if iQuantity then
- turtle.transferTo(iTo,iQuantity)
- else
- turtle.transferTo(iTo)
- end
- turtle.select(iCurr)
- end
- function refuel(iAmount,iSlot, iDamage) --needed because we depend on fuel level
- if type(iSlot)=="string" then
- for i=1,16 do
- if tTurtleData.tInventory[i] and tTurtleData.tInventory[i].name==iSlot and (not iDamage or tTurtleData.tInventory[i].damage==iDamage) then
- iSlot = i
- break
- elseif not tTurtleData.tInventory[i] and iSlot=="empty" then
- iSlot = i
- break
- end
- end
- end
- if type(iSlot)=="string" then
- return false
- end
- if iSlot then
- turtle.select(iSlot)
- end
- updatePosition()
- local ok = iAmount and turtle.refuel(iAmount) or turtle.refuel() --because of a bug in the function
- if ok then --if we refueled then
- tTurtleData.iFuel = turtle.getFuelLevel() --set our amount to the current level
- return true
- end
- return false --otherwise, return false
- end
- function setData(iX,iY,iZ,sFaceing,tEquipLeft,tEquipRight,iFuel,tInventory) --update internal data
- tTurtleData = {
- tPosition = {x=iX,y=iY,z=iZ},--position
- sFacing = sFacing,--direction
- tEquipment = {tLeft=tEquipLeft,tRight=tEquipRight},--equipment
- iFuel = iFuel or turtle.getFuelLevel(),--fuel
- sMove = "none",--since we are changing everything there was no last movement
- tInventory = tInventory or fGetInventory(),
- }
- end
- function updateData()
- local iX, iY, iZ = gps.locate(2)
- if iX then
- tPos = turtle.sFacing and turtle.tPosition
- if tPos and (tPos.x~=iX or tPos.y~=iY or tPos.z~=iZ) then
- while not turtle.forward() do --attempt to move forward
- if not turtle.detect() and not turtle.attack() then --if there isnt a block or mob
- turtle.refuel()
- end
- end
- local iNewX,iNewY,iNewZ = gps.locate(2) --where are we now?
- tTurtleData.sFacing = ({[-1]={[0]="north"},[0]={[-1]="west",[1]="east"},[1]={[0]="south"}})[iX-iNewX][iZ-iNewZ] --determine our direction
- if not turtle.back() then
- iX,iZ=iNewX,iNewZ --if we couldnt go back go ahead and make this the new position and stay
- end
- end
- tTurtleData.tPosition = {x=iX,y=iY,z=iZ}
- for i=1,16 do --find an empty slot
- if turtle.getItemCount(i)==0 then
- turtle.select(i)
- break
- end
- if i==16 then --no empty slot? make one
- turtle.select(i)
- turtle.dropUp()
- end
- end
- turtle.equipLeft()
- tTurtleData.tEquipment.tLeft = turtle.getItemDetail() --what is in our left hand?
- turtle.equipLeft()
- turtle.equipRight()
- tTurtleData.tEquipment.tRight = turtle.getItemDetail() --what is in our right hand?
- turtle.equipRight()
- turtle.suckUp() --if we dropped an item earlier lets try to pick it up
- tTurtleData.sMove = "none"
- tTurtleData.iFuel = turtle.getFuelLevel()
- tTurtleData.tInventory = fGetInventory()
- return true
- else
- return false
- end
- end
- function getData() --get our internal data
- updatePosition() --update position first though so its accurate
- return tTurtleData.handle
- end
- function pos()
- updatePosition() --update first
- return tTurtleData.handle.tPosition
- end
- function getLeft() --left hand
- return tTurtleData.handle.tEquipment.tLeft
- end
- function getRight() --right hand
- return tTurtleData.handle.tEquipment.tRight
- end
- function getEquip() --both hands
- return tTurtleData.handle.tEquipment
- end
- --no hands
- function facing()
- return tTurtleData.handle.sFacing
- end
- function inventory()
- return tTurtleData.handle.tInventory
- end
- function becomeTurtle()
- turtle = {}
- for k, v in next, _G.turtle do --first we need to fix our local turtle table so we don't start any loops
- turtle[k] = v
- end
- for k, v in next, getfenv() do --then we put ourselves in the global turtle table
- _G.turtle[k] = v
- end
- end
- function forwardForce(iNum) --move forward no matter what
- if iNum == 0 then
- return true
- end
- iNum = iNum or 1
- local bValid, iInternal
- if tTurtleData.iFuel >= iNum then
- repeat
- bValid, iInternal = forward(iNum)
- if iInternal then
- iNum = iNum - iInternal
- turtle.dig()
- turtle.attack()
- end
- until bValid
- end
- end
- function backForce(iNum) --move backward no matter what
- if iNum == 0 then
- return true
- end
- iNum = iNum or 1
- local bValid, iInternal
- if tTurtleData.iFuel >= iNum then
- repeat
- bValid, iInternal = back(iNum)
- if iInternal then
- iNum = iNum - iInternal
- reverse()
- turtle.dig()
- turtle.attack()
- reverse()
- end
- until bValid
- end
- end
- function upForce(iNum) --move up no matter what
- if iNum == 0 then
- return true
- end
- iNum = iNum or 1
- local bValid, iInternal
- if tTurtleData.iFuel >= iNum then
- repeat
- bValid, iInternal = up(iNum)
- if iInternal then
- iNum = iNum - iInternal
- turtle.digUp()
- turtle.attackUp()
- end
- until bValid
- end
- end
- function downForce(iNum) --move down no matter what
- if iNum == 0 then
- return true
- end
- iNum = iNum or 1
- local bValid, iInternal
- if tTurtleData.iFuel >= iNum then
- repeat
- bValid, iInternal = down(iNum)
- if iInternal then
- iNum = iNum - iInternal
- turtle.digDown()
- turtle.attackDown()
- end
- until bValid
- end
- end
- function strafeRightForce(iNum)
- if iNum == 0 then
- return true
- end
- turnRight()
- iNum = iNum or 1
- local bValid, iInternal
- if tTurtleData.iFuel >= iNum then
- repeat
- bValid, iInternal = forward(iNum)
- if iInternal then
- iNum = iNum - iInternal
- turtle.dig()
- turtle.attack()
- end
- until bValid
- end
- turnLeft()
- end
- function strafeLeftForce(iNum)
- if iNum == 0 then
- return true
- end
- turnLeft()
- iNum = iNum or 1
- local bValid, iInternal
- if tTurtleData.iFuel >= iNum then
- repeat
- bValid, iInternal = forward(iNum)
- if iInternal then
- iNum = iNum - iInternal
- turtle.dig()
- turtle.attack()
- end
- until bValid
- end
- turnRight()
- end
- tTurtleData.tInventory = fGetInventory()
- function undo(iNum)
- local tEnv = getfenv()
- for i=1,iNum or 1 do
- if #tLog.handle>0 then
- tEnv[table.remove(tLog.handle,#tLog.handle)]()
- table.remove(tLog.handle,#tLog.handle)
- tTurtleData.tLog = tLog.handle
- end
- end
- end
- function undoAll(iNum)
- undo(#tLog.handle)
- end
- function undoForce(iNum)
- local tEnv = getfenv()
- for i=1,iNum or 1 do
- if #tLog.handle>0 then
- local func = table.remove(tLog.handle,#tLog.handle)
- if tEnv[func.."Force"] then
- tEnv[func.."Force"]()
- else
- tEnv[func]()
- end
- table.remove(tLog.handle,#tLog.handle)
- tTurtleData.tLog = tLog.handle
- end
- end
- end
- function undoAllForce(iNum)
- undo(#tLog.handle)
- end
- function clearLog()
- tLog.handle = {}
- tTurtleData.tLog = tLog
- end
- function goto(iX,iY,iZ)
- updatePosition()
- while (iX-tTurtleData.tPosition.x)/tFacing[tTurtleData.sFacing].iMulti<0 or tFacing[tTurtleData.sFacing].sForward~="x" do
- turnLeft()
- end
- forwardForce(math.abs(iX-tTurtleData.tPosition.x))
- while (iZ-tTurtleData.tPosition.z)/tFacing[tTurtleData.sFacing].iMulti<0 or tFacing[tTurtleData.sFacing].sForward~="z" do
- turnLeft()
- end
- forwardForce(math.abs(iZ-tTurtleData.tPosition.z))
- if (iY-tTurtleData.tPosition.y) < 0 then
- downForce(math.abs(iY-tTurtleData.tPosition.y))
- else
- upForce(math.abs(iY-tTurtleData.tPosition.y))
- end
- end
- local tDigAllPos = {}
- local function fClearPos()
- tDigAllPos = {}
- end
- local function fAddPos(x,y,z)
- if not y then
- x,y,z = x.x,x.y,x.z
- end
- if not tDigAllPos[x] then
- tDigAllPos[x] = {}
- end
- if not tDigAllPos[x][y] then
- tDigAllPos[x][y] = {}
- end
- tDigAllPos[x][y][z] = true
- end
- local function fGetPos(tPos)
- return tDigAllPos[tPos.x] and tDigAllPos[tPos.x][tPos.y] and tDigAllPos[tPos.x][tPos.y][tPos.z]
- end
- local function fFixPos(tPos)
- return {x=tPos.x,y=tPos.y,z=tPos.z}
- end
- local function internalDigAll(fInspect,fStartMove)
- local bOk, sName,success = fInspect()
- local iStart = #tLog.handle
- if not bOk then
- return false
- else
- sName = sName.name
- end
- fClearPos()
- fStartMove()
- fAddPos(pos())
- local tPos
- local iInternalTurns = 0
- repeat
- tPos = fFixPos(pos())
- tPos[tFacing[tTurtleData.sFacing].sForward] = tPos[tFacing[tTurtleData.sFacing].sForward] + tFacing[tTurtleData.sFacing].iMulti
- if not fGetPos(tPos) then
- bOk, sInternalName = turtle.inspect()
- fAddPos(tPos)
- else
- bOk = false
- end
- success = bOk and sInternalName.name == sName
- if not success then
- tPos = fFixPos(pos())
- tPos[tFacing.up.sForward] = tPos[tFacing.up.sForward] + tFacing.up.iMulti
- if not fGetPos(tPos) then
- bOk, sInternalName = turtle.inspectUp()
- fAddPos(tPos)
- else
- bOk = false
- end
- success = bOk and sInternalName.name == sName
- if not success then
- tPos = fFixPos(pos())
- tPos[tFacing.down.sForward] = tPos[tFacing.down.sForward] + tFacing.down.iMulti
- if not fGetPos(tPos) then
- bOk, sInternalName = turtle.inspectDown()
- fAddPos(tPos)
- else
- bOk = false
- end
- success = bOk and sInternalName.name == sName
- if success then
- downForce()
- iInternalTurns = -1
- end
- else
- upForce()
- iInternalTurns = -1
- end
- else
- forwardForce()
- iInternalTurns = -1
- end
- if iInternalTurns == -1 then
- iInternalTurns = 0
- elseif iInternalTurns == 4 then
- for i=1,4 do
- table.remove(tLog.handle,#tLog.handle)
- end
- undoForce()
- iInternalTurns = 0
- while tLog.handle[#tLog.handle]=="turnRight" and #tLog.handle > iStart do
- undoForce()
- end
- else
- turnLeft()
- iInternalTurns = iInternalTurns + 1
- end
- updatePosition()
- until #tLog.handle == iStart
- end
- function digAll()
- internalDigAll(turtle.inspect,forwardForce)
- end
- function digAllUp()
- internalDigAll(turtle.inspectUp,upForce)
- end
- function digAllDown()
- internalDigAll(turtle.inspectDown,backForce)
- end
Advertisement
Add Comment
Please, Sign In to add comment