tps
Description
A collection of all my ComputerCraft programs and the APIs they use. This is mostly just to get them the fuck off of pastebin, and also to ensure that API owners don't change things to break my precious programs...!
Installation
Copy one of these commands into your ComputerCraft terminal:
wget:
wget https://raw.githubusercontent.com/LDDestroier/CC/master/tps.lua tpsArchive:
wget https://cc.shobie.xyz/cc/get/gh-LDDestroier-CC-tps tps
Quick Install:
wget https://cc.shobie.xyz/cc/get/gh-LDDestroier-CC-tps tps
Usage
Run: tps
Tags
Source
View Original SourceCode Preview
--[[
Turtle Positioning System
Use two turtles as an expensive and crappy GPS server! Use ALL the fuel!
wget https://raw.githubusercontent.com/LDDestroier/CC/master/tps.lua
std ld tps tps.lua
--]]
local chestX = 0 -- fill this in!
local chestY = 0 -- fill this in!
local chestZ = 0 -- fill this in!
local startx,starty,startz --if there isn't a file storing them
startx = 0
starty = 64
startz = 0
local chest = true
if not gps then -- I love error handling
return printError("GPS API wasn't found. Are you using an older version of ComputerCraft?")
else
if type(gps) == "table" then
if not (gps.locate) then
return printError("gps.locate seems to be missing.")
else
if type(gps.locate) == "string" then
return printError("Is this a joke? gps.locate is a string. This does not make sense.")
elseif type(gps.locate) == "table" then
return printError("What the... gps.locate is a table! Knock it off.")
elseif type(gps.locate) == "number" then
return printError("Eh? gps.locate is a number! This doesn't ADD UP!")
end
end
end
end
local cfilename = ".coords"
local tArg = {...}
local modem = peripheral.find("modem")
if not turtle then
if pocket then
return printError("Yo dipshit, pocket computers can't run TPS.")
else
return printError("Er. This is a turtle program, you know?")
end
end
if not modem then
local l = peripheral.wrap("right")
local r = peripheral.wrap("left")
if r and l then
return printError("Dangit, you messed up! Craft a WIRELESS turtle!")
else
return printError("You need a wireless modem.")
end
end
modem.open(gps.CHANNEL_GPS)
local tew,tps
local requests = 0
local scr_x, scr_y = term.getSize()
local fuels = {
["minecraft:coal"] = 80,
["minecraft:coal_block"] = 80*9,
}
local dro = function(input)
return input % 4
end
local fixNumber = function(num)
return math.floor(num+0.5)
end
local getDist = function(x1,y1,z1,x2,y2,z2)
return math.abs(x2-x1)+math.abs(y2-y1)+math.abs(z2-z1)
end
local directionNames = {
[0] = "South",
[1] = "West",
[2] = "North",
[3] = "East",
}
local dudes = {}
local total
local sendRequest = function()
total = 0
for k,v in pairs(dudes) do
if v > 0 then
modem.transmit( k, gps.CHANNEL_GPS, { tew.x, tew.y, tew.z } )
dudes[k] = dudes[k] - 1
requests = requests + 1
total = total + 1
end
end
tew.lock = (total == 0)
end
local adjustCoords = function(dir, dist)
if dir == -1 then
tew.y = tew.y + 1
elseif dir == -2 then
tew.y = tew.y - 1
else
tew.x = fixNumber(tew.x - math.sin(math.rad(dir*90)))
tew.z = fixNumber(tew.z + math.cos(math.rad(dir*90)))
end
tps(true)
end
local gotoCoords = function( gx, gy, gz )
if (gx == tew.x) and (gy == tew.y) and (gz == tew.z) then
return
end
local cx,cy,cz = tew.x,tew.y,tew.z
while (gx ~= tew.x) or (gy ~= tew.y) or (gz ~= tew.z) do
for a = 1, math.abs(gy-cy) do
if tew.y == gy then
break
end
tew.lock = false
if gy > cy then
tew.up()
else
tew.down()
end
end
if tew.x ~= gx then
tew.lock = false
tew.turn(3)
for a = 1, math.abs(gx-cx) do
if tew.x == gx then
break
end
tew.lock = false
if gx > cx then
tew.forward()
else
tew.back()
end
end
end
if tew.z ~= gz then
tew.lock = false
tew.turn(0)
for a = 1, math.abs(gz-cz) do
if tew.z == gz then
break
end
tew.lock = false
if gz > cz then
tew.forward()
else
tew.back()
end
end
end
end
end
local saveTheWhales = function() --HOPEFULLY the path is unobstructed by blocks
local bC = {
x = tew.x,
y = tew.y,
z = tew.z,
direction = tew.direction,
}
gotoCoords(chestX,((chestY>bC.y) and (chestY-1) or (chestY+1)),chestZ)
for a = 1, 16 do
if turtle.inspectUp() then
turtle.suckUp()
elseif turtle.inspectDown() then
turtle.suckDown()
elseif turtle.inspect() then
turtle.suck()
end
end
gotoCoords(bC.x,bC.y,bC.z)
tew.lock = false
tew.turn(bC.direction)
end
local checkIfCanFuel = function()
local currentSlot = turtle.getSelectedSlot()
for a = 1, 16 do
local item = turtle.getItemDetail(a)
if item then
if fuels[item.name] then
return true
end
end
end
return false
end
local doRefuel = function()
while true do
local currentSlot = turtle.getSelectedSlot()
for a = 1, 16 do
local item = turtle.getItemDetail(a)
if item then
if fuels[item.name] then
turtle.select(a)
turtle.refuel(1)
turtle.select(currentSlot)
term.setCursorPos(1,scr_y)
term.clearLine()
return true
end
end
end
sleep(0) -- INSERT MORE FUEL!
term.setCursorPos(1,scr_y)
term.write("Insert more fuel!!")
end
return false
end
local handleFuel = function(chest)
if type(turtle.getFuelLevel()) == "number" then
if chest and (not checkIfCanFuel()) then
local dist = getDist(tew.x,tew.y,tew.z,chestX,chestY,chestZ)
if dist+10 > turtle.getFuelLevel() then -- gives me some leeway
saveTheWhales() -- PANIC
doRefuel()
end
end
if turtle.getFuelLevel() == 0 then
doRefuel()
end
else
return true
end
end
-- 'tew' is a reproduction of the turtle API, but tracked and written to a file located at cfilename (default: "/.coords")
tew = { --already localized
lock = false,
direction = 0,
x = startx,
y = starty,
z = startz,
forward = function(dist,doFuelThing)
local success, msg
for a = 1, dist or 1 do
if tew.lock then
repeat
sleep(0)
until not tew.lock
end
handleFuel(doFuelThing)
success, msg = turtle.forward()
if success then
adjustCoords(dro(tew.direction),1)
--os.queueEvent("tew_move")
sendRequest()
else
return success, msg
end
end
return true
end,
back = function(dist,doFuelThing)
local success, msg
for a = 1, dist or 1 do
if tew.lock then
repeat
sleep(0)
until not tew.lock
end
handleFuel(doFuelThing)
success, msg = turtle.back()
if success then
adjustCoords(dro(tew.direction+2),1)
--os.queueEvent("tew_move")
sendRequest()
else
return success, msg
end
end
return true
end,
up = function(dist,doFuelThing)
local success, msg
for a = 1, dist or 1 do
if tew.lock then
repeat
sleep(0)
until not tew.lock
end
handleFuel(doFuelThing)
success, msg = turtle.up()
if success then
adjustCoords(-1,1)
--os.queueEvent("tew_move")
sendRequest()
else
return success, msg
end
end
return true
end,
down = function(dist,doFuelThing)
local success, msg
for a = 1, dist or 1 do
if tew.lock then
repeat
sleep(0)
until not tew.lock
end
handleFuel(doFuelThing)
success, msg = turtle.down()
if success then
adjustCoords(-2,1)
--os.queueEvent("tew_move")
sendRequest()
else
return success, msg
end
end
return true
end,
turnRight = function(times,doFuelThing)
handleFuel(doFuelThing)
for a = 1, times or 1 do
if tew.lock then
repeat
sleep(0)
until not tew.lock
end
turtle.turnRight()
tew.direction = dro(tew.direction+1)
tps(true)
end
return true
end,
turnLeft = function(times,doFuelThing)
handleFuel(doFuelThing)
for a = 1, times or 1 do
if tew.lock then
repeat
sleep(0)
until not tew.lock
end
turtle.turnRight()
tew.direction = dro(tew.direction+1)
tps(true)
end
return true
end,
turn = function(dir)
if dir == tew.direction then
return true
end
repeat
tew.turnRight()
until tew.direction == dir
return true
end
}
tps = function( doWrite )
if doWrite then
local file = fs.open(cfilename,"w")
file.write(tew.x.."\n"..tew.y.."\n"..tew.z.."\n"..tew.direction.."\n"..chestX.."\n"..chestY.."\n"..chestZ)
file.close()
else
if not fs.exists(cfilename) then
tps(true)
end
local file = fs.open(cfilename,"r")
tew.x = tonumber(file.readLine())
tew.y = tonumber(file.readLine())
tew.z = tonumber(file.readLine())
tew.direction = tonumber(file.readLine())
chestX = tonumber(file.readLine())
chestY = tonumber(file.readLine())
chestZ = tonumber(file.readLine())
file.close()
end
end
tps(false)
tew.lock = true
local doTurtleMove = function()
while true do
tew.forward( 1,true)
tew.turnRight( 1,true)
tew.forward( 1,true)
tew.up( 1,true)
tew.turnRight( 1,true)
tew.forward( 1,true)
tew.turnRight( 1,true)
tew.forward( 1,true)
tew.down( 1,true)
tew.turnRight( 1,true)
end
end
local handleRequests = function() --also handles manual exit
local evt, side, chan, repchan, message, distance
while true do
evt, side, chan, repchan, message, distance = os.pullEvent()
if evt == "modem_message" then
if (chan == gps.CHANNEL_GPS) and (message == "PING") then
dudes[repchan] = 4
--os.queueEvent("tew_receive")
sendRequest()
end
elseif evt == "key" then
if side == keys.x then
return
end
end
end
end
local getEvents = function(...)
local evt
while true do
evt = {os.pullEvent()}
for a = 1, #arg do
if arg[a] == evt[1] then
return unpack(evt)
end
end
end
end
local colClearLine = function(col,y,char)
local cbg,ctxt,cx,cy = term.getBackgroundColor(), term.getTextColor(), term.getCursorPos()
local scr_x,scr_y = term.getSize()
term.setCursorPos(1,y or cy)
term.setBackgroundColor(col or cbg)
term.write((char or " "):rep(scr_x))
term.setBackgroundColor(cbg)
term.setTextColor(ctxt)
term.setCursorPos(cx,cy)
end
local prettyPrint = function(left,right)
local ctxt = term.getTextColor()
term.setTextColor(term.isColor() and colors.yellow or colors.lightGray)
write(left)
term.setTextColor(ctxt)
print(right)
end
local displayData = function()
while true do
term.clear()
term.setCursorPos(1,1)
colClearLine(colors.gray)
prettyPrint("\nFuel: ",turtle.getFuelLevel())
prettyPrint("X/Y/Z: ",tew.x.."/"..tew.y.."/"..tew.z)
prettyPrint("Direction: ",tew.direction.." ("..directionNames[tew.direction]..")")
prettyPrint("Requests: ",requests)
colClearLine(colors.gray)
print("\nPress 'X' to exit.")
sleep(0)
end
end
local displayHelp = function()
local data = [[
Turtle GPS System (TPS)
by LDDestroier/EldidiStroyrr
Place a chest down, and fill it with fuel.
Place the turtle down (you did), and specify its own coordinates ('1') and the chest coordinates ('2').
Start!]]
print(data)
sleep(0.1)
os.pullEvent("key")
end
local okaythen = false
while not okaythen do
term.clear()
term.setCursorPos(1,1)
print()
print("Push '1' to change coordinates...")
print("Push '2' to change chest coordinates...")
print("Push 'X' to cancel...")
print("Push 'Spacebar' to start immediately...")
local _x,_y = term.getCursorPos()
local buttmode = 0
local res = parallel.waitForAny(
function()
while true do
local _,char = os.pullEvent("char")
if char:lower() == "1" then
buttmode = 1
return
elseif char:lower() == "2" then
buttmode = 2
return
elseif char:lower() == " " then
okaythen = true
return
elseif char:lower() == "x" then
buttmode = -1
return
end
end
end,
function()
for a = 1, 3*10 do
term.setCursorPos(_x,_y)
term.write("Starting in "..(3-(a/10)).." seconds...")
sleep(0.1)
end
end)
if res == 1 then
term.clear()
term.setCursorPos(1,1)
if buttmode == 1 then
print("Turtle position input.")
colClearLine(colors.white)
write("\nX: ")
tew.x = tonumber(read()) or tew.x
write("Y: ")
tew.y = tonumber(read()) or tew.y
write("Z: ")
tew.z = tonumber(read()) or tew.z
print("Direction (F3 -> 'f'): ")
for k,v in pairs(directionNames) do
print(" "..k.." = '"..v.."'")
end
write(">")
tew.direction = tonumber(read()) or tew.direction
tps(true)
elseif buttmode == 2 then
print("Refuel Chest input.")
colClearLine(colors.white)
write("\nChest X: ")
chestX = tonumber(read()) or chestX
write("Chest Y: ")
chestY = tonumber(read()) or chestY
write("Chest Z: ")
chestZ = tonumber(read()) or chestZ
tps(true)
elseif buttmode == -1 then
print("Cancelled.")
error()
end
else
okaythen = true
end
end
parallel.waitForAny(
handleRequests,
doTurtleMove,
displayData
)
term.setCursorPos(1, scr_y-2)
print("Thank you for using TPS!")
sleep(0)