Posted 03 December 2012 - 10:07 AM
I would appreciate any help testing the api.
main part that needs testing is the goTo function, to determine any bugs in the pathing system. it will attempt to go around any obstacle 5 blocks in radius, but I have not extensively tested inside any large buildings with many halls and corridors.
These are some turtle programs I made to get stuff done, some have been modified from others I've seen, but most ended up getting re-written from scratch. Most of the them will rely on the turtle api which I made, which I named capi, so to use them, you would need to name the api the same.
Notes:
I have a habit of using z for the vertical coordinate and y for the horizontal, and format Cartesian coordinates as (x,y,z), so you will notice that some of the functions will accept as that format.
The relative directions maintain the same chirality of the minecraft coordinate system, so in the smartmining program, the cardinal directions are based on the initial direction being set to south.
capi:
Note: the strip function needs to be updated to say second to last slot, last is now for fuel
pastebin: http://pastebin.com/az1ePpke
The main program i use when using this api is "stuff", here is that file:
pastebin: http://pastebin.com/tnE2eGKR
I also have one for smartmining with ASTU:
pastebin: http://pastebin.com/QJK7Zb2b
If you see anything that needs improving, or have ideas on how to improve them, please let me know.
Disclaimer:
I do not know much about the LUA programming language, or of programming in general (what i know is mainly based on one semester of C class), so any programming specific terminology i may not know or understand.
main part that needs testing is the goTo function, to determine any bugs in the pathing system. it will attempt to go around any obstacle 5 blocks in radius, but I have not extensively tested inside any large buildings with many halls and corridors.
These are some turtle programs I made to get stuff done, some have been modified from others I've seen, but most ended up getting re-written from scratch. Most of the them will rely on the turtle api which I made, which I named capi, so to use them, you would need to name the api the same.
Notes:
I have a habit of using z for the vertical coordinate and y for the horizontal, and format Cartesian coordinates as (x,y,z), so you will notice that some of the functions will accept as that format.
The relative directions maintain the same chirality of the minecraft coordinate system, so in the smartmining program, the cardinal directions are based on the initial direction being set to south.
capi:
Note: the strip function needs to be updated to say second to last slot, last is now for fuel
pastebin: http://pastebin.com/az1ePpke
Spoiler
-- Variables
local positionx, positionz, positiony, facing = 0,0,0,0 -- these are absolute coords
local x0,y0,z0, f0 = 0,0,0,0
local posx, posz, posy, posf = 0, 0, 0, 0 -- these are relative coords
local cx, cz, cy, cf = 0,0,0,0 -- these are coords of chest for mining
local tx,ty,tz,tf, tt = 0,0,0,0,0 -- these are temp cooreds
local dx,dy,dz,df = 0,0,0,0 -- these are difference in coords
local cslot = 1
local dirset, posset = false, false
local pi = math.pi
local root3 = (3^0.5)
local collected = 0
local unloaded = 0
local build = false
local triedx, triedy, triedz, turned, moved, tryturn, digtunnel, done, drop, modem = false, false, false, 0, true,0,false,false,true,true
local var = 5
local n = 6
local sOpenedSide = nil
errormsgmodem = true
msgreadfile = true
safemove = true
msg1 = false
function r0abs() return vector.new(positionx,positiony,positionz) end
function r0rel() return vector.new(posx,posy,posz) end
function r(targetx,targety,targetz) return vector.new(targetx,targety,targetz) end
-- Functions
--internal variable setters.
function safeMove(var)
safemove = var
end
function Done(var)
done = var
end
--position Related Functions
function open()
local bOpen, sFreeSide = false, nil
for n,sSide in pairs(rs.getSides()) do
if peripheral.getType( sSide ) == "modem" then
sFreeSide = sSide
if rednet.isOpen( sSide ) then
bOpen = true
break
end
end
end
if not bOpen then
if sFreeSide then
rednet.open( sFreeSide )
sOpenedSide = sFreeSide
modem = true
return true
else
if errormsgmodem then
print( "No modem attached" )
errormsgmodem = false
end
modem = false
return false
end
end
modem = true
return true
end
function gpspos()
if not open() then
remloc()
return positionx, positionz, positiony, facing
end
if open() then
if gps.locate(5, false) == false then
remloc()
else
positionx, positionz, positiony = gps.locate(5,false)
if not dirset then
facing = setDir()
end
posset = true
saveloc()
return positionx, positionz, positiony, facing
end
elseif not posset then
print("I are not wireless turtle! Please manually set absolute position in file capi/pos")
if fs.exists("capi/pos","r") then
local fLocation = fs.open("capi/pos","r")
positionx = tonumber(fLocation.readLine())
positionz = tonumber(fLocation.readLine())
positiony = tonumber(fLocation.readLine())
facing = tonumber(fLocation.readLine())
fLocation.close()
posset = true
else
error("location file not found")
end
else
remloc()
return positionx, positionz, positiony, facing
end
saveloc()
return positionx, positionz, positiony, facing
end
function saveloc()
local fLocation = fs.open("capi/pos","w")
fLocation.writeLine(positionx)
fLocation.writeLine(positionz)
fLocation.writeLine(positiony)
fLocation.writeLine(facing)
fLocation.writeLine(posx)
fLocation.writeLine(posz)
fLocation.writeLine(posy)
fLocation.writeLine(posf)
fLocation.close()
end
function remloc()
if msgreadfile then
print("reading location file")
msgreadfile = false
end
local fLocation = fs.open("capi/pos","r")
positionx = tonumber(fLocation.readLine())
positionz = tonumber(fLocation.readLine())
positiony = tonumber(fLocation.readLine())
facing = tonumber(fLocation.readLine())
posx = tonumber(fLocation.readLine())
posz = tonumber(fLocation.readLine())
posy = tonumber(fLocation.readLine())
posf = tonumber(fLocation.readLine())
fLocation.close()
return positionx, positionz, positiony, facing, posx, posz, posy, posf
end
function setDir()
open()
if modem then
x1, positionz, y1 = gps.locate(5,false)
fd = forwardTrack()
if fd then
x2, positionz, y2 = gps.locate(5,false)
backTrack()
if x2 > x1 then
facing = 3
elseif x1 > x2 then
facing = 1
elseif y2 > y1 then
facing = 0
elseif y1 > y2 then
facing = 2
end
dirset = true
return facing
elseif not fd then
bk = backTrack()
x2, positionz, y2 = gps.locate(5,false)
forwardTrack()
if bk then
if x2 > x1 then
facing = 1
elseif x1 > x2 then
facing = 3
elseif y2 > y1 then
facing = 2
elseif y1 > y2 then
facing = 0
end
dirset = true
return facing
end
end
if not bk then
turnLeftTrack()
end
fd = forwardTrack()
if fd then
x2, positionz, y2 = gps.locate(5,false)
turtle.back()
if x2 > x1 then
facing = 3
elseif x1 > x2 then
facing = 1
elseif y2 > y1 then
facing = 0
elseif y1 > y2 then
facing = 2
end
dirset = true
turnRightTrack()
return facing
end
if not fd then
bk = backTrack()
x2, positionz, y2 = gps.locate(5,false)
forwardTrack()
if bk then
if x2 > x1 then
facing = 1
elseif x1 > x2 then
facing = 3
elseif y2 > y1 then
facing = 2
elseif y1 > y2 then
facing = 0
end
dirset = true
turnRightTrack()
return facing
end
else
dirset = false
error("cannot move to check location")
end
elseif not msg1 then
print("no modem attached, using position file")
msg1 = true
end
end
function zeropos()
remloc()
posx, posz, posy, posf = 0,0,0,0
print("Relative position zeroed")
local fLocation = fs.open("capi/pos","w")
fLocation.writeLine(positionx)
fLocation.writeLine(positionz)
fLocation.writeLine(positiony)
fLocation.writeLine(facing)
fLocation.writeLine(posx)
fLocation.writeLine(posz)
fLocation.writeLine(posy)
fLocation.writeLine(posf)
fLocation.close()
end
function relpos()
return posx, posz, posy, posf
end
function getloc(loc)
loc = tostring(loc)
if not fs.exists("locations/"..loc) then
error("unknown location")
end
local fLocation = fs.open("locations/"..loc,"r")
x = tonumber(fLocation.readLine())
z = tonumber(fLocation.readLine())
y = tonumber(fLocation.readLine())
f = tonumber(fLocation.readLine())
sx = tonumber(fLocation.readLine())
sz = tonumber(fLocation.readLine())
sy = tonumber(fLocation.readLine())
sf = tonumber(fLocation.readLine())
fLocation.close()
return x, z, y, f, sx, sz, sy, sf
end
function goTo(loc, val)
loc = tostring(loc)
x, z, y, f, sx, sz, sy, sf = getloc(loc)
if val == nil then
val = true
end
if val == (abs or true) then
CargoTo(x,y,z)
face(f)
elseif val == (rel or false) then
CartesiangoTo(sx,sy,sz)
facef(sf)
end
end
-- Misc Functions
function refuel()
if turtle.getFuelLevel() == "unlimited" then
return true
end
if turtle.getFuelLevel() > 10 then
return true
end
if turtle.getFuelLevel() <= 10 then
turtle.select(16)
if not turtle.refuel() then
for i = 1,15 do
turtle.select(i)
if turtle.getFuelLevel() < 10 then
turtle.refuel()
else
return true
end
end
end
end
if turtle.getFuelLevel() < 10 then
error("Cannot find Fuel")
end
end
function unload()
print( "Unloading items..." )
unloaded = 0
if not digtunnel then
for n=1,15 do
unloaded = unloaded + turtle.getItemCount(n)
turtle.select(n)
turtle.drop()
end
collected = 0
turtle.select(1)
else
for n=1,14 do
unloaded = unloaded + turtle.getItemCount(n)
turtle.select(n)
turtle.drop()
end
collected = 0
turtle.select(1)
end
end
function unloadDown()
print( "Unloading items..." )
unloaded = 0
if not digtunnel then
for n=1,15 do
unloaded = unloaded + turtle.getItemCount(n)
turtle.select(n)
turtle.dropDown()
end
collected = 0
turtle.select(1)
else
for n=1,14 do
unloaded = unloaded + turtle.getItemCount(n)
turtle.select(n)
turtle.dropDown()
end
collected = 0
turtle.select(1)
end
end
function round(num)
under = math.floor(num)
upper = math.ceil(num)
test = num - under
if (test <= 0.50) then
return under
else
return upper
end
end
function isitodd(num)
oddtest1 = num/2
oddtest2 = round(oddtest1)
if oddtest1 ~= oddtest2 then
return true
else
return false
end
end
function collect()
local bFull = true
local nTotalItems = 0
if build then
return true
end
for n=1,15 do
local nCount = turtle.getItemCount(n)
if nCount == 0 then
bFull = false
end
nTotalItems = nTotalItems + nCount
end
if nTotalItems > collected then
collected = nTotalItems
if math.fmod(collected + unloaded, 50) == 0 then
print( "Mined "..(collected + unloaded).." items." )
end
end
if bFull then
print( "No empty slots left." )
return false
end
return true
end
function chestlocation()
if safemove then
cx, cz, cy, cf = gpspos()
else
cx, cz, cy, cf = relpos()
end
print("chest location set")
end
function returnsupplies()
print("Returning to chest")
x, z, y, f = 0,0,0,0
if safemove then
x, z, y, f = gpspos()
CargoTo(cx, cy, cz)
face(cf)
elseif not safemove then
x, z, y, f = relpos()
CartesiangoTo(cx, cy, cz)
facef(cf)
end
if drop == true then
unload()
end
if not done then
print("returning to previous location")
if safemove then
CargoTo(x, y, z)
face(f)
else
CartesiangoTo(x, y, z)
facef(f)
end
end
end
function distance(targetx,targety,targetz,val) -- val is true for absolute, if no val, it will take relative position.
if val == nil then
val = false
end
rtarget = vector.new(targetx,targety,targetz)
if val then
rprime = rtarget - r0abs()
return rprime:length()
else
rprime = rtarget - r0rel()
return rprime:length()
end
end
-- these dig anything that gets in the way
function safeForward()
success = false
while not success do
success = forwardTrack()
if not success then
turtle.dig()
success = forwardTrack()
if not collect() then
returnsupplies()
end
end
end
end
function safeUp()
success = false
while not success do
success = upTrack()
if not success then
turtle.digUp()
success = upTrack()
if not collect() then
returnsupplies()
end
end
end
end
function safeDown()
success = false
while not success do
success = downTrack()
if not success then
turtle.digDown()
success = downTrack()
if not collect() then
returnsupplies()
end
end
end
end
--the move functions will mine anything that gets in the way
function moveY(targety)
if targety == posy then
return
end
dycheck = targety - posy
while targety ~= posy do
if dycheck > 0 then
facef(0)
else
facef(2)
end
safeForward()
if targety == posy then
return
end
end
end
function moveX(targetx)
if targetx == posx then
return
end
dxcheck = targetx - posx
while targetx ~= posx do
if dxcheck > 0 then
facef(3)
else
facef(1)
end
safeForward()
if targety == posy then
return
end
end
end
function moveZ(targetz)
if targetz == posz then
return
end
while targetz > posz do
safeUp()
end
while targetz < posz do
safeDown()
end
end
--place functions for generic building, will place any block in inventory
function placeDown()
if turtle.getItemCount(cslot) == 0 then
foundSlot = false
while not foundSlot do
for i = 1,15 do
if turtle.getItemCount(i) > 0 then
foundSlot = i
break
end
end
if not foundSlot then
-- No resources
print("Out of building materials. Please refill and press enter to continue.")
io.read()
end
end
cslot = foundSlot
turtle.select(foundSlot)
end
if not turtle.compareDown() then
turtle.digDown()
turtle.placeDown()
end
end
function placeForward()
if turtle.getItemCount(cslot) == 0 then
foundSlot = false
while not foundSlot do
for i = 1,15 do
if turtle.getItemCount(i) > 0 then
foundSlot = i
break
end
end
if not foundSlot then
-- No resources
print("Out of building materials. Please refill and press enter to continue.")
io.read()
end
end
cslot = foundSlot
turtle.select(foundSlot)
end
if not turtle.compare() then
turtle.dig()
turtle.place()
end
end
function placeUp()
if turtle.getItemCount(cslot) == 0 then
foundSlot = false
while not foundSlot do
for i = 1,15 do
if turtle.getItemCount(i) > 0 then
foundSlot = i
break
end
end
if not foundSlot then
-- No resources
print("Out of building materials. Please refill and press enter to continue.")
io.read()
end
end
cslot = foundSlot
turtle.select(foundSlot)
end
if not turtle.compareUp() then
turtle.digUp()
turtle.placeUp()
end
end
-- position tracking functions, return either success state (boolean) or direction (the face functions)
function aboutFace()
turnLeftTrack()
turnLeftTrack()
end
function face(direction) -- face absolute
if not dirset then
setDir()
end
if direction == (facing + 1) then
turnRightTrack()
elseif direction == (facing - 1) then
turnLeftTrack()
elseif direction == (facing + 2) then
turnLeftTrack()
turnLeftTrack()
elseif direction == (facing - 2) then
turnLeftTrack()
turnLeftTrack()
elseif direction == 0 and facing == 3 then
turnRightTrack()
elseif direction == 3 and facing == 0 then
turnLeftTrack()
elseif direction == facing then
saveloc()
return facing
end
saveloc()
return facing
end
function facef(direction) --face relative
if not dirset then
setDir()
end
if direction == (posf + 1) then
turnRightTrack()
elseif direction == (posf - 1) then
turnLeftTrack()
elseif direction == (posf + 2) then
turnLeftTrack()
turnLeftTrack()
elseif direction == (posf - 2) then
turnLeftTrack()
turnLeftTrack()
elseif direction == 0 and posf == 3 then
turnRightTrack()
elseif direction == 3 and posf == 0 then
turnLeftTrack()
elseif diection == posf then
saveloc()
return posf
end
saveloc()
return posf
end
function turnRightTrack()
turtle.turnRight()
turned = turned + 1
facing = facing + 1
posf = posf + 1
if facing >= 4 then
facing = 0
end
if posf >= 4 then
posf = 0
end
saveloc()
end
function turnLeftTrack()
turtle.turnLeft()
turned = turned + 1
facing = facing - 1
posf = posf - 1
if facing < 0 then
facing = 3
end
if posf < 0 then
posf = 3
end
saveloc()
end
function forwardTrack()
refuel()
fd = turtle.forward()
if fd then
turned = 0
moved = true
if facing == 0 then
positiony = positiony + 1
elseif facing == 2 then
positiony = positiony - 1
elseif facing == 1 then
positionx = positionx - 1
elseif facing == 3 then
positionx = positionx + 1
end
if posf == 0 then
posy = posy + 1
elseif posf == 2 then
posy = posy - 1
elseif posf == 1 then
posx = posx - 1
elseif posf == 3 then
posx = posx + 1
end
saveloc()
return true
else
moved = false
return false
end
end
function backTrack()
refuel()
bk = turtle.back()
if bk then
moved = true
turned = 0
if facing == 2 then
positiony = positiony + 1
elseif facing == 0 then
positiony = positiony - 1
elseif facing == 3 then
positionx = positionx - 1
elseif facing == 1 then
positionx = positionx + 1
end
if posf == 2 then
posy = posy + 1
elseif posf == 0 then
posy = posy - 1
elseif posf == 3 then
posx = posx - 1
elseif posf == 1 then
posx = posx + 1
end
saveloc()
return true
else
moved = false
return false
end
end
function upTrack()
refuel()
up = turtle.up()
if up then
moved = true
turned = 0
positionz = positionz + 1
posz = posz + 1
saveloc()
return true
else
moved = false
return false
end
end
function downTrack()
refuel()
down = turtle.down()
if down then
moved = true
turned = 0
positionz = positionz - 1
posz = posz - 1
saveloc()
return true
else
moved = false
return false
end
end
--The m functions do not remove anything that gets in the way. They attempt to go around obstacles.
function mY(targetx, targety, targetz)
dx,dy,dz = targetx - positionx, targety - positiony, targetz - positionz
if dy == 0 then
saveloc()
return true
end
while dy ~= 0 do
--face right direction
if dy > 0 then
face(0)
else
face(2)
end
--try moving forward
turtlemove = forwardTrack()
dx,dy,dz = targetx - positionx, targety - positiony, targetz - positionz
if not turtlemove then
triedy = true
end
if turtlemove then
triedx = false
triedz = false
if dx == dy == dz == 0 then
saveloc()
return true
end
elseif not triedx and (dx ~= 0) then
mX(targetx,targety,targetz)
elseif not triedz and (dz ~= 0) then
mZ(targetx,targety,targetz)
elseif tryLeft() then
mY(targetx, targety, targetz)
elseif tryRight() then
mY(targetx, targety, targetz)
elseif tryOver() then
mY(targetx, targety, targetz)
elseif tryUnder() then
mY(targetx, targety, targetz)
else
backTrack()
mX(targetx,targety,targetz)
end
end
end
function mX(targetx, targety, targetz)
dx,dy,dz = targetx - positionx, targety - positiony, targetz - positionz
if dx == 0 then
saveloc()
return true
end
while dx ~= 0 do
if dx > 0 then
face(3)
else
face(1)
end
turtlemove = forwardTrack()
dx,dy,dz = targetx - positionx, targety - positiony, targetz - positionz
if not turtlemove then
triedx = true
end
if turtlemove then
triedy = false
triedz = false
if (dx == dy == dz == 0) then
saveloc()
return true
end
elseif not triedy and (dy ~= 0) then
mY(targetx,targety,targetz)
elseif not triedz and (dz ~= 0) then
mZ(targetx,targety,targetz)
elseif tryLeft() then
mX(targetx, targety, targetz)
elseif tryRight() then
mX(targetx, targety, targetz)
elseif tryOver() then
mX(targetx, targety, targetz)
elseif tryUnder() then
mX(targetx, targety, targetz)
else
backTrack()
mY(targetx,targety,targetz)
end
end
end
function mZ(targetx, targety, targetz)
dzcheck = targetz - positionz
if targetz == positionz then
saveloc()
return
end
while targetz ~= positionz do
if dzcheck > 0 then
up = upTrack()
if up then
triedy = false
triedx = false
end
if not up then
triedz = true
if not triedy and (positiony ~= targety) then
mY(targetx,targety,targetz)
elseif not triedx and (positionx ~= targetx) then
mX(targetx,targety,targetz)
elseif tryLeft() then
mZ(targetx, targety, targetz)
elseif tryRight() then
mZ(targetx, targety, targetz)
elseif tryOver() then
mZ(targetx, targety, targetz)
elseif tryUnder() then
mZ(targetx, targety, targetz)
end
end
else
down = downTrack()
if down then
triedy = false
triedx = false
end
if not down then
triedz = true
if not triedy and (positiony ~= targety) then
mY(targetx,targety,targetz)
elseif not triedx and (positionx ~= targetx) then
mX(targetx,targety,targetz)
elseif tryLeft() then
mZ(targetx, targety, targetz)
elseif tryRight() then
mZ(targetx, targety, targetz)
elseif tryOver() then
mZ(targetx, targety, targetz)
elseif tryUnder() then
mZ(targetx, targety, targetz)
end
end
end
end
end
function tryLeft()
x,z,y,f = gpspos()
turnLeftTrack()
fd = forwardTrack()
if not fd then
turnRightTrack()
return false
end
for j = 1, n do
if j ~= 1 then
fd = forwardTrack()
if not fd then
CargoTo(x,y,z)
face(f)
return false
end
end
turnRightTrack()
fd = forwardTrack()
if fd then
return true
else
turnLeftTrack()
end
end
if not fd then
CargoTo(x,y,z)
face(f)
return false
end
end
function tryRight()
x,z,y,f = gpspos()
turnRightTrack()
fd = forwardTrack()
if not fd then
turnLeftTrack()
return false
end
for j = 1, n do
if j ~= 1 then
fd = forwardTrack()
if not fd then
CargoTo(x,y,z)
face(f)
return false
end
end
turnLeftTrack()
fd = forwardTrack()
if fd then
return true
else
turnRightTrack()
end
end
if not fd then
CargoTo(x,y,z)
face(f)
return false
end
end
function tryOver()
x,z,y,f = gpspos()
up = upTrack()
if not up then
return false
end
for j = 1,n do
fd = forwardTrack()
if fd then
return true
else
upTrack()
end
end
if not fd then
CargoTo(x,y,z)
face(f)
return false
end
end
function tryUnder()
x,z,y,f = gpspos()
down = downTrack()
if not down then
return false
end
for j = 1,n do
fd = forwardTrack()
if fd then
return true
else
downTrack()
end
end
if not fd then
CargoTo(x,y,z)
face(f)
return false
end
end
--cartesian, spherical and cylindrical gotos will remove any block that gets in the way.
function CartesiangoTo(targetx, targety, targetz)
if posz < targetz then
moveZ(targetz)
if posx > targetx then
moveY(targety)
moveX(targetx)
else
moveX(targetx)
moveY(targety)
end
else
if posy > targety then
moveX(targetx)
moveY(targety)
else
moveY(targety)
moveX(targetx)
end
moveZ(targetz)
end
end
function SphericalgoTo(R, theta, phi)
if phi <= (2*pi + 1/R) and theta <= (pi+1/R) and phi >= 0 and theta >= 0 then
x = (R*math.cos(phi)*math.sin(theta))
y = (R*math.sin(phi)*math.sin(theta))
z = (R*math.cos(theta))
Rtest = (x^2+y^2+z^2)^0.5
Rup = R + 1
if (round(Rtest) == R) and (math.floor(Rtest + root3) == Rup) then
x = round(x)
y = round(y)
z = round(z)
if posz > 0 then
moveZ(z)
if (phi < pi/2 and 0 <= phi) or (phi < 3*pi/2 and pi <= phi) then
moveX(x)
moveY(y)
elseif (phi < pi and pi/2 <= phi) or (phi < 2*pi and 3*pi/2 <= phi) then
moveY(y)
moveX(x)
end
else
if (phi < pi/2 and 0 <= phi) or (phi < 3*pi/2 and pi <= phi) then
moveX(x)
moveY(y)
elseif (phi < pi and pi/2 <= phi) or (phi < 2*pi and 3*pi/2 <= phi) then
moveY(y)
moveX(x)
end
moveZ(z)
end
end
end
end
function CylindricalgoTo(R, phi, z)
if phi <= 2*pi then
x = round(R*math.cos(phi))
y = round(R*math.sin(phi))
Rtest = (x^2+y^2)^0.5
Rup = R+1
if R == 1 then
CartesiangoTo(x,y,z)
elseif (round(Rtest) == R) and (math.floor(Rtest + root3) == Rup) then
CartesiangoTo(x,y,z)
end
end
end
--CargoTo, CylgoTo and SphgoTo will not remove any blocks.
function CargoTo(targetx, targety, targetz)
local triesx, triesy, triesz = true, true, true
gpspos()
if facing == 1 or facing == 3 then -- X axis
if(targetz > positionz) then
mZ(targetx, targety, targetz)
mY(targetx, targety, targetz)
mX(targetx, targety, targetz)
else
mY(targetx, targety, targetz)
mX(targetx, targety, targetz)
mZ(targetx, targety, targetz)
end
else
if(targetz > positionz) then
mZ(targetx, targety, targetz)
mX(targetx, targety, targetz)
mY(targetx, targety, targetz)
else
mX(targetx, targety, targetz)
mY(targetx, targety, targetz)
mZ(targetx, targety, targetz)
end
end
if (positionx == targetx) and (positiony == targety) and (positionz == targetz) then
try = 0
return true
end
if (positionx ~= targetx) or (positiony ~= targety) or (positionz ~= targetz) then
CargoTo(targetx, targety, targetz)
try = try + 1
if try > 3 then
try = 0
error("why I in wrong spot?")
end
end
end
function CylgoTo(R, phi, z)
if phi <= 2*pi then
x = round(R*math.cos((phi)))
y = round(R*math.sin((phi)))
Rtest = (x^2+y^2)^0.5
Rup = R+1
if R == 1 then
CargoTo(x,y,z)
elseif (round(Rtest) == R) and (math.floor(Rtest + root3) == Rup) then
CargoTo(x,y,z)
end
end
end
function SphgoTo(R, theta, phi)
if phi <= (2*pi + 1/(2*R)) and theta <= (pi+1/(2*R)) then
x = round(R*math.cos(phi)*math.sin(theta))
y = round(R*math.sin(phi)*math.sin(theta))
z = round(R*math.cos(theta))
Rtest = round((x^2+y^2+z^2)^0.5)
Rup = R+1
if (round(Rtest) == R) and (math.floor(Rtest + root3) == Rup) then
CargoTo(x, y, z)
end
end
end
--The "build stuff" functions
function buildTower(number,radius) --builds a circular tower
turtle.select(1)
h = number * (radius + 1)
R = radius
for z = 1,h do
for phi=0,2*pi,1/(4*R) do
CylindricalgoTo(R,phi,z)
placeDown()
end
end
CargoTo(0,0,positionz)
face(0)
end
function buildFloors(number,radius) --builds circular floors
downTrack()
for i=1,number do
Radius = radius
NegRadius = 0 - Radius
n = radius + 2
k = i
z = positionz
--make the floors
for R=1,radius do
for phi=0,2*pi,1/(4*R) do
CylindricalgoTo(R,phi,z)
placeDown()
end
end
CargoTo(0,0,positionz)
placeDown()
CargoTo(0,NegRadius,positionz)
--go down to next floor
if k ~= number then
turtle.digDown()
end
if k < number then
for i=1,n do
downTrack()
end
end
CargoTo(0,0,positionz)
placeDown()
face(0, facing)
end
--make the doorway
CargoTo(0,Radius,positionz)
if turtle.detect() then
turtle.dig()
else
turnLeftTrack()
turnLeftTrack()
turtle.dig()
end
upTrack()
turtle.dig()
downTrack()
placeDown()
CargoTo(0,0,positionz)
placeDown()
face(0)
end
function digSphere(radius) --dig out a sphere downwards
chestlocation()
safeDown()
zeropos()
posz = radius
for R = 0,radius do
for theta = 0,pi,1/((2^0.5)*R) do
pr = R * math.sin(theta)
for phi = 0, 2*pi, 1/(10*pr) do
SphericalgoTo(R,theta,phi)
end
end
end
CartesiangoTo(0,0,0)
done = true
returnsupplies()
done = false
end
function digShaft(depth, radius)
for i=1,depth do
z = -i
for R=1,radius do
for phi=0,2*pi,1/(4*R) do
CylindricalgoTo(R,phi,z)
end
end
end
CartesiangoTo(0,0,z)
CartesiangoTo(0,0,0)
end
function digRoom(depth,width,height) -- digs out a cuboid room
local x0,z0,y0, f0 = gpspos()
facef(2)
chestlocation()
facef(0)
safeForward()
posx, posz, posy, posf = 0, 0, 0, 0
turtle.digUp()
safeForward()
depth = depth + 1
width = width + 1
height = height
limit = math.floor((width - 1)/2)
for k = 0, (height-1) do
for j = 1,(depth+1) do
if posx < 0 then
for i = -(limit+1), (limit+1) do
-- print("going to" ..i.. ", " ..j.. ", " ..posz.. " from " ..posx.. ", " ..posy.. ", " ..posz)
CartesiangoTo(i,j,k)
end
else
for i = -(limit+1), (limit+1) do
-- print("going to" ..i.. ", " ..j.. ", " ..posz.. " from " ..posx.. ", " ..posy.. ", " ..posz)
CartesiangoTo(-i,j,k)
end
end
end
end
done = true
CartesiangoTo(0,2,0)
returnsupplies()
done = false
end
function digStrip(length) --digs a 3 x 1 tunnel and places torchs every 8 blocks
digtunnel = true
print("ensure that the last slot has enough torches")
print("Press any key to continue")
while true do
event, param1 = os.pullEvent()
if event == "char" then
break
end
end
if (length/8) > 64 then
error("I cannot hold " ..(length/8).. " torches in the last slot")
end
if turtle.getItemCount(15) < (length/8) then
error("not enough torches")
end
print("digging line " ..length.. " long.")
local n = 0
facef(2)
chestlocation()
facef(0)
safeUp()
for i=1, length do
safeForward()
n = n + 1
turtle.digDown()
if n == 8 then
turtle.select(15)
turtle.placeDown()
n = 0
end
while turtle.detectUp() do
turtle.digUp()
sleep(0.3)
end
end
done = true
drop = false
returnsupplies()
done = false
drop = true
digtunnel = false
end
function buildTunnel(length) --builds a tunnel and places torches every 5 blocks
print( "Building Tunnel" )
build = true
count = 0
facef(2)
chestlocation()
facef(0)
for n=1,length do
safeForward()
turtle.select(1)
placeDown()
turtle.turnLeft()
safeForward()
turtle.select(2)
placeDown()
turtle.select(3)
placeForward()
for n=4,5 do
safeUp()
turtle.select(n)
placeForward()
end
turtle.select(6)
placeUp()
turtle.turnRight()
turtle.turnRight()
safeForward()
turtle.select(7)
placeUp()
safeDown()
safeDown()
safeForward()
turtle.select(8)
placeDown()
turtle.select(9)
placeForward()
for n=10,11 do
safeUp()
turtle.select(n)
placeForward()
end
turtle.select(12)
placeUp()
turtle.turnLeft()
turtle.turnLeft()
safeForward()
safeDown()
safeDown()
turtle.turnRight()
count = count + 1
if count > 5 then
turtle.turnLeft()
upTrack()
turtle.select(15)
turtle.place()
downTrack()
turtle.turnRight()
count = 0
end
end
print( "Returning to start..." )
done = true
returnsupplies()
done = false
print( "Tunnel complete." )
end
function digTunnel(length) --digs a tunnel and places torches every 5 blocks
print( "Digging Tunnel" )
digtunnel = true
count = 0
local x0,z0,y0, f0 = gpspos()
turnRightTrack()
turnRightTrack()
chestlocation()
turnLeftTrack()
turnLeftTrack()
for n=1,length do
safeForward()
turnLeftTrack()
safeForward()
for n=4,5 do
safeUp()
end
turnRightTrack()
turnRightTrack()
safeForward()
safeDown()
safeDown()
safeForward()
for n=10,11 do
safeUp()
end
turnLeftTrack()
turnLeftTrack()
safeForward()
safeDown()
safeDown()
turnRightTrack()
count = count + 1
if count > 5 then
turnLeftTrack()
safeUp()
safeForward()
if not turtle.detect() then
turtle.select(14)
turtle.place()
end
backTrack()
turtle.select(15)
turtle.place()
safeDown()
turnRightTrack()
count = 0
end
end
print( "Returning to start..." )
done = true
returnsupplies()
done = false
print( "Tunnel complete." )
digtunnel = false
end
function buildDome(radius) --builds a dome
print("building dome of radius " ..radius)
turtle.select(1)
savez = positionz
positionz = -1
R = radius
for theta = (-pi/2),0,1/(R) do
angle = 0 - theta
pr = R * math.sin(angle)
for phi = 0, 2*pi, 1/(2*pr^2) do
SphericalgoTo(R,angle,phi)
placeDown()
end
end
CartesiangoTo(0,0,positionz)
placeDown()
gpspos()
end
function buildRoom(depth, width, height)
turtle.select(1)
build = true
local x0,z0,y0, f0 = gpspos()
zeropos()
depth = depth + 1
width = width + 1
height = height + 1
limit = math.floor((width - 1)/2)
-- Build the floor
for j = 1,(depth+1) do
if posx < 0 then
for i = -(limit+1), (limit+1) do
-- print("going to" ..i.. ", " ..j.. ", " ..posz.. " from " ..posx.. ", " ..posy.. ", " ..posz)
CartesiangoTo(i,j,posz)
placeDown()
end
else
for i = -(limit+1), (limit+1) do
-- print("going to" ..i.. ", " ..j.. ", " ..posz.. " from " ..posx.. ", " ..posy.. ", " ..posz)
CartesiangoTo(-i,j,posz)
placeDown()
end
end
end
-- Build the Walls
for k = 1,height do
for i = 0, -(limit+1) do
CartesiangoTo(i,1,k)
placeDown()
end
for j = 1,(depth+1) do
CartesiangoTo(-(limit+1),j,k)
placeDown()
end
for i = -(limit+1), (limit+1) do
CartesiangoTo(i,(depth+1),k)
placeDown()
end
for j = -(depth+1),-1 do
CartesiangoTo((limit+1),-j,k)
placeDown()
end
for i = -(limit+1), (limit + 1) do
CartesiangoTo(-i, 1, k)
placeDown()
end
end
--build the roof
for j = 1,(depth) do
if posx < 0 then
for i = -(limit), (limit) do
-- print("going to" ..i.. ", " ..j.. ", " ..posz.. " from " ..posx.. ", " ..posy.. ", " ..posz)
CartesiangoTo(i,j,posz)
placeDown()
end
else
for i = -(limit), (limit) do
--print("going to" ..i.. ", " ..j.. ", " ..posz.. " from " ..posx.. ", " ..posy.. ", " ..posz)
CartesiangoTo(-i,j,posz)
placeDown()
end
end
end
--return to start
CargoTo(x0,y0,z0)
facef(0)
build = false
end
--auto run functions at startup
if not fs.isDir("capi") then
fs.makeDir("capi")
saveloc()
gpspos()
end
The main program i use when using this api is "stuff", here is that file:
pastebin: http://pastebin.com/tnE2eGKR
Spoiler
local arg = { ... }
type = arg[1]
if not fs.isDir("locations") then
fs.makeDir("locations")
end
if type == "tower" then
if #arg ~= 3 then
print( "Usage: tower <floors> <radius>")
return
end
floors = tonumber(arg[2])
radius = tonumber(arg[3])
Radius = radius - 1
capi.zeropos()
capi.buildTower(floors, radius)
capi.buildFloors(floors, Radius)
elseif type == "shaft" then
if #arg ~= 3 then
print( "Usage: shaft <depth> <radius>")
return
end
depth = tonumber(arg[2])
radius = tonumber(arg[3])
capi.zeropos()
capi.digShaft(depth, radius)
elseif type == "room" then
if #arg ~= 4 then
print( "Usage: room <depth> <width> <height>")
return
end
depth = tonumber(arg[2])
width = tonumber(arg[3])
height = tonumber(arg[4])
--capi.zeropos()
capi.digRoom(depth,width,height)
elseif type == "build" and arg[2] == "room" then
if #arg ~= 5 then
print( "Usage: build room <depth> <width> <height>")
return
end
depth = tonumber(arg[3])
width = tonumber(arg[4])
height = tonumber(arg[5])
capi.buildRoom(depth,width,height)
elseif type == "sphere" then
if #arg ~= 2 then
print( "Usage: sphere <radius>")
return
end
radius = tonumber(arg[2])
capi.digSphere(radius)
elseif type == "tunnel" then
if #arg ~= 2 then
print( "Usage: tunnel <length>")
return
end
length = tonumber(arg[2])
capi.zeropos()
capi.buildTunnel(length)
elseif (type == "dig") and (arg[2] == "tunnel") then
if #arg ~= 3 then
print( "Usage: dig tunnel <length>")
return
end
length = tonumber(arg[3])
capi.digTunnel(length)
elseif type == "dome" then
if #arg ~= 2 then
print( "Usage: dome <radius>")
return
end
radius = tonumber(arg[2])
capi.zeropos()
capi.buildDome(radius)
elseif type == "strip" then
if #arg ~= 2 then
print( "Usage: Strip <length>")
return
end
length = tonumber(arg[2])
capi.digStrip(length)
elseif type == "goto" then
capi.setDir()
x0,z0,y0,f0 = capi.gpspos()
phi = f0
if #arg == 3 then
x = tonumber(arg[2])
z = tonumber(arg[3])
y = z0
elseif #arg == 4 then
x = tonumber(arg[2])
y = tonumber(arg[3])
z = tonumber(arg[4])
elseif #arg == 5 then
x = tonumber(arg[2])
y = tonumber(arg[3])
z = tonumber(arg[4])
phi = tonumber(arg[5])
elseif #arg == 2 then
local location = arg[2]
local fLocation = fs.open("locations/"..location,"r")
x = tonumber(fLocation.readLine())
y = tonumber(fLocation.readLine())
z = tonumber(fLocation.readLine())
phi = tonumber(fLocation.readLine())
fLocation.close()
print("Going to "..location.."...")
else
error("Unknown location.")
end
capi.CargoTo(x,z,y)
if #arg ~= 4 then
capi.face(math.floor(phi))
end
elseif type == "saveloc" then
if not fs.isDir("locations") then
fs.makeDir("locations")
end
if #arg == 1 then
capi.saveloc()
return
end
local location = arg[2]
xname, yname, zname, phi = capi.gpspos()
x,z,y,f = capi.relpos()
if not fs.exists("locations/"..location) then
local fLocation = fs.open("locations/"..location,"w")
fLocation.writeLine(xname)
fLocation.writeLine(yname)
fLocation.writeLine(zname)
fLocation.writeLine(phi)
fLocation.writeLine(x)
fLocation.writeLine(z)
fLocation.writeLine(y)
fLocation.writeLine(f)
fLocation.close()
fLocation.close()
print("Location \""..location.."\" added.")
else
print("This location already exists. Would you like to replace it?\n\(y/n\)")
while true do
event, character = os.pullEvent()
if event == "char" and character == "y" then
local fLocation = fs.open("locations/"..location,"w")
fLocation.writeLine(xname)
fLocation.writeLine(yname)
fLocation.writeLine(zname)
fLocation.writeLine(phi)
fLocation.close()
print("Location changed.")
break
elseif event == "char" and character == "n" then
print("Location not changed.")
break
end
end
end
else
print("valid options are tower, shaft, room, sphere, dome, saveloc, dig tunnel, goto and tunnel")
os.exit(1)
end
I also have one for smartmining with ASTU:
pastebin: http://pastebin.com/QJK7Zb2b
Spoiler
arg = { ... }
length = tonumber(arg[1])
if #arg == 0 then
length = 1
end
if #arg == 2 then
up = true
else
up = false
end
ores = {14, -- Gold
15, -- Iron
16, -- Coal
21, -- Lapis Lazuli
49, -- Obsidian
56, -- Dimond
73, -- Redstone
129, -- Emerald
247, -- uranium
253,
2501,
901,
910}
orex = { nil }
orey = { nil }
orez = { nil }
beenx = { nil }
beeny = { nil }
beenz = { nil }
oredists = { nil }
local mine = true
count = 0
scanned = false
closest = 0
local detectID = peripheral.wrap("right")
local function isFull()
for n=16,1,-1 do
if turtle.getItemCount(n) < 1 then
turtle.select(1)
return false
end
end
return true
end
local function OreDown()
if not turtle.detectDown() then
return false
end
id = detectID.IDetectDown()
num = #ores
for i = 1,num do
test = ores[i]
if (id == test) then
return true
end
end
return false
end
local function OreUp()
if not turtle.detectUp() then
return false
end
id = detectID.IDetectUp()
num = #ores
for i = 1,num do
test = ores[i]
if (id == test) then
return true
end
end
return false
end
local function OreNorth()
capi.facef(2)
if not turtle.detect() then
return false
end
id = detectID.IDetect()
num = #ores
for i = 1,num do
test = ores[i]
if (id == test) then
return true
end
end
return false
end
local function OreSouth()
capi.facef(0)
if not turtle.detect() then
return false
end
id = detectID.IDetect()
num = #ores
for i = 1,num do
test = ores[i]
if (id == test) then
return true
end
end
return false
end
local function OreEast()
capi.facef(3)
if not turtle.detect() then
return false
end
id = detectID.IDetect()
num = #ores
for i = 1,num do
test = ores[i]
if (id == test) then
return true
end
end
return false
end
local function OreWest()
capi.facef(1)
if not turtle.detect() then
return false
end
id = detectID.IDetect()
num = #ores
for i = 1,num do
test = ores[i]
if (id == test) then
return true
end
end
return false
end
local function Scan()
scanned = true
x,z,y,f = capi.relpos()
if OreUp() then
n = table.maxn(orex)
scanned = false
for i = 1,n do
if ((orex[i] == x) and (orey[i] == y) and (orez[i] == z+1)) then
scanned = true
end
end
if not scanned then
table.insert(orex, x)
table.insert(orey, y)
table.insert(orez, z+1)
end
end
if OreDown() then
n = table.maxn(orex)
scanned = false
for i = 1,n do
if ((orex[i] == x) and (orey[i] == y) and (orez[i] == z-1)) then
scanned = true
end
end
if not scanned then
table.insert(orex, x)
table.insert(orey, y)
table.insert(orez, z-1)
end
end
if OreSouth() then
n = table.maxn(orex)
scanned = false
for i = 1,n do
if ((orex[i] == x) and (orey[i] == y+1) and (orez[i] == z)) then
scanned = true
end
end
if not scanned then
table.insert(orex, x)
table.insert(orey, y+1)
table.insert(orez, z)
end
end
if OreWest() then
n = table.maxn(orex)
scanned = false
for i = 1,n do
if ((orex[i] == x-1) and (orey[i] == y) and (orez[i] == z)) then
scanned = true
end
end
if not scanned then
table.insert(orex, x-1)
table.insert(orey, y)
table.insert(orez, z)
end
end
if OreNorth() then
n = table.maxn(orex)
scanned = false
for i = 1,n do
if ((orex[i] == x) and (orey[i] == y-1) and (orez[i] == z)) then
scanned = true
end
end
if not scanned then
table.insert(orex, x)
table.insert(orey, y-1)
table.insert(orez, z)
end
end
if OreEast() then
n = table.maxn(orex)
scanned = false
for i = 1,n do
if ((orex[i] == x+1) and (orey[i] == y) and (orez[i] == z)) then
scanned = true
end
end
if not scanned then
table.insert(orex, x+1)
table.insert(orey, y)
table.insert(orez, z)
end
end
if orex[1] == nil then
return false
end
capi.facef(f)
return true
end
function Mine()
Scan()
n = table.maxn(orex)
if orex[1] == nil then
return false
end
while n > 0 do
k = 1
for i = 1,n do
oredists[i] = capi.distance(orex[i], orey[i], orez[i], false)
end
for j = 1,(n-1) do
if oredists[k] ~= nil then
if oredists[j] < oredists[k] then
k = j
end
end
end
capi.CartesiangoTo(tonumber(orex[k]), tonumber(orey[k]), tonumber(orez[k]))
count = count + 1
table.remove(orex, k)
table.remove(orey, k)
table.remove(orez, k)
table.remove(oredists, k)
Scan()
n = table.maxn(orex)
end
return true
end
capi.safeMove(false)
capi.zeropos()
capi.facef(2)
capi.chestlocation()
capi.facef(0)
for j = 1,length do
Mine()
if up then
turtle.digUp()
end
capi.CartesiangoTo(0,j,0)
end
capi.CartesiangoTo(0,0,0)
print("mined "..count.." ore")
capi.returnsupplies()
capi.safeMove(true)
If you see anything that needs improving, or have ideas on how to improve them, please let me know.
Disclaimer:
I do not know much about the LUA programming language, or of programming in general (what i know is mainly based on one semester of C class), so any programming specific terminology i may not know or understand.