Advertisement
Lyqyd

GPS Setup

Apr 5th, 2014
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.43 KB | None | 0 0
  1. local args = {...}
  2.  
  3. local startupFile = [[while not turtle.detectDown() do
  4.     turtle.down()
  5. end
  6.  
  7. if not os.getComputerLabel() then os.setComputerLabel("gpsSetup") end
  8. if fs.exists("/nsh") then
  9.     shell.run("nsh host rom/programs/shell beacon")
  10. else
  11.     shell.run("beacon")
  12. end
  13. ]]
  14.  
  15. local beaconFile = [[local modem
  16. for _, side in pairs(rs.getSides()) do
  17.     if peripheral.getType(side) == "modem" then
  18.         modem = peripheral.wrap(side)
  19.         break
  20.     end
  21. end
  22.  
  23. if modem then
  24.     while true do
  25.         modem.transmit(65532, os.getComputerID(), "beacon")
  26.         os.startTimer(1)
  27.         local event = {os.pullEvent()}
  28.         if event[1] == "char" and event[2] == "q" then
  29.             fs.delete("beacon")
  30.             fs.delete("startup")
  31.             return
  32.         end
  33.     end
  34. end
  35. ]]
  36.  
  37. local diskStartup = [=[if turtle then
  38.     shell.run("/startup")
  39. else
  40.     if fs.exists("/disk/nsh") then
  41.         fs.copy("/disk/nsh", "/nsh")
  42.     end
  43.     if fs.exists("/disk/get") then
  44.         fs.copy("/disk/get", "/get")
  45.     end
  46.     if fs.exists("/disk/put") then
  47.         fs.copy("/disk/put", "/put")
  48.     end
  49.     fs.copy("/disk/gpsStart", "/gpsStart")
  50.     local file = io.open("/startup", "w")
  51.     if file then
  52.         if fs.exists("/nsh") then
  53.             file:write([[shell.run("nsh host /rom/programs/shell gpsStart")]].."\n")
  54.         else
  55.             file:write([[shell.run("gpsStart")]])
  56.             file:close()
  57.         end
  58.     end
  59.     if fs.exists("/disk/label") then
  60.         local file = io.open("/disk/label", "r")
  61.         if file then
  62.             os.setComputerLabel(file:read("*a"))
  63.             file:close()
  64.         end
  65.     end
  66. end
  67. ]=]
  68.  
  69. local function writeLocalFiles()
  70.     local handle = io.open("startup", "w")
  71.     if handle then
  72.         handle:write(startupFile)
  73.         handle:close()
  74.     end
  75.     local handle = io.open("beacon", "w")
  76.     if handle then
  77.         handle:write(beaconFile)
  78.         handle:close()
  79.     end
  80. end
  81.  
  82. local function writeDiskFiles()
  83.     local handle = io.open("disk/startup", "w")
  84.     if handle then
  85.         handle:write(diskStartup)
  86.         handle:close()
  87.     end
  88.     if not fs.exists("disk/nsh") and fs.exists("nsh") then fs.copy("nsh", "disk/nsh") end
  89.     if not fs.exists("disk/get") and fs.exists("get") then fs.copy("nsh", "disk/get") end
  90.     if not fs.exists("disk/put") and fs.exists("put") then fs.copy("nsh", "disk/put") end
  91. end
  92.  
  93. local function printCenter(text)
  94.     text = tostring(text)
  95.     local x, y = term.getSize()
  96.     local xCur, yCur = term.getCursorPos()
  97.     term.setCursorPos((x - #text) / 2 + 1, yCur)
  98.     term.write(text)
  99. end
  100.  
  101. local headingNames = {"West", "North", "East", "South"}
  102.  
  103. local location = {}
  104. local Location = {
  105.     add = function(self, o)
  106.         return vector.new(
  107.             self.x + o.x,
  108.             self.y + o.y,
  109.             self.z + o.z
  110.         )
  111.     end,
  112.     sub = function(self, o)
  113.         return vector.new(
  114.             self.x - o.x,
  115.             self.y - o.y,
  116.             self.z - o.z
  117.         )
  118.     end,
  119.     mul = function(self, m)
  120.         return vector.new(
  121.             self.x * m,
  122.             self.y * m,
  123.             self.z * m
  124.         )
  125.     end,
  126.     div = function(self, d)
  127.         return vector.new(
  128.             self.x / d,
  129.             self.y / d,
  130.             self.z / d
  131.         )
  132.     end,
  133.     left = function(self, noMove)
  134.         self.h = self.h - 1
  135.         if self.h < 1 then self.h = self.h + 4 end
  136.         return noMove or turtle.turnLeft()
  137.     end,
  138.     right = function(self, noMove)
  139.         self.h = self.h + 1
  140.         if self.h > 4 then self.h = self.h - 4 end
  141.         return noMove or turtle.turnRight()
  142.     end,
  143.     forward = function(self, noMove)
  144.         if noMove or turtle then
  145.             if noMove or turtle.forward() then
  146.                 self.x = self.x + (self.h - 2) * (self.h % 2)
  147.                 self.z = self.z + (self.h - 3) * ((self.h + 1) % 2)
  148.                 return true
  149.             end
  150.         end
  151.         return false
  152.     end,
  153.     back = function(self, noMove)
  154.         if turtle then
  155.             if turtle.back() then
  156.                 self.x = self.x - (self.h - 2) * (self.h % 2)
  157.                 self.z = self.z - (self.h - 3) * ((self.h + 1) % 2)
  158.                 return true
  159.             end
  160.         end
  161.         return false
  162.     end,
  163.     up = function(self, noMove)
  164.         if noMove or turtle then
  165.             if noMove or turtle.up() then
  166.                 self.y = self.y + 1
  167.                 return true
  168.             end
  169.         end
  170.         return false
  171.     end,
  172.     down = function(self, noMove)
  173.         if noMove or turtle then
  174.             if noMove or turtle.down() then
  175.                 self.y = self.y - 1
  176.                 return true
  177.             end
  178.         end
  179.         return false
  180.     end,
  181.     moveDeltas = function(self)
  182.         return (self.h - 2) * (self.h % 2), (self.h - 3) * ((self.h + 1) % 2)
  183.     end,
  184.     setHeading = function(self, head)
  185.         if not head or head < 1 or head > 4 then return nil, "Heading Not in Range" end
  186.         while self.h ~= head do
  187.             if (self.h + 1) % 4 == head % 4 then
  188.                 self:right()
  189.             else
  190.                 self:left()
  191.             end
  192.         end
  193.     end,
  194.     tovector = function(self)
  195.         if vector then
  196.             return vector.new(
  197.                 self.x,
  198.                 self.y,
  199.                 self.z
  200.             )
  201.         else
  202.             return nil
  203.         end
  204.     end,
  205.     tostring = function(self)
  206.         return self.x..","..self.y..","..self.z..","..self.h
  207.     end,
  208.     value = function(self)
  209.         return self.x, self.y, self.z, self.h
  210.     end,
  211. }
  212.  
  213. local lmetatable = {
  214.     __index = Location,
  215.     __add = Location.add,
  216.     __sub = Location.sub,
  217.     __mul = Location.mul,
  218.     __div = Location.div,
  219.     __unm = function(l) return l:mul(-1) end,
  220.     __tostring = function(l) return l:tostring() end,
  221. }
  222.  
  223. function location.new( x, y, z, h )
  224.     local l = {
  225.         x = x or 0,
  226.         y = y or 0,
  227.         z = z or 0,
  228.         h = h or 1
  229.     }
  230.     setmetatable( l, lmetatable )
  231.     return l
  232. end
  233.  
  234. function location.getOrientation(x, z)
  235.     return ((x + math.abs(x) * 2) + (z + math.abs(z) * 3))
  236. end
  237.  
  238. local function moveTo (moveLoc, loc)
  239.     while loc.x ~= moveLoc.x or loc.z ~= moveLoc.z do
  240.         local moveX, moveZ
  241.         if math.abs(moveLoc.x - loc.x) > math.abs(moveLoc.z - loc.z) then
  242.             magnitude = math.abs(moveLoc.x - loc.x)
  243.             moveX = (moveLoc.x - loc.x) / math.abs(moveLoc.x - loc.x)
  244.             moveZ = 0
  245.         else
  246.             magnitude = math.abs(moveLoc.z - loc.z)
  247.             moveZ = (moveLoc.z - loc.z) / math.abs(moveLoc.z - loc.z)
  248.             moveX = 0
  249.         end
  250.         loc:setHeading(location.getOrientation(moveX, moveZ))
  251.         while magnitude > 0 do
  252.             if loc:forward() then
  253.                 magnitude = magnitude - 1
  254.             else
  255.                 loc:left()
  256.                 loc:forward()
  257.                 loc:right()
  258.             end
  259.         end
  260.     end
  261.     while loc.y ~= moveLoc.y do
  262.         deltaY = moveLoc.y - loc.y
  263.         if deltaY > 0 then
  264.             loc:up()
  265.         else
  266.             loc:down()
  267.         end
  268.     end
  269.     return loc:setHeading(moveLoc.h)
  270. end
  271.  
  272. local function setupSatellite(satLoc, loc)
  273.     moveTo(satLoc, loc)
  274.     loc:back()
  275.     turtle.select(1)
  276.     turtle.place()
  277.     loc:down()
  278.     turtle.select(3)
  279.     turtle.place()
  280.     turtle.select(4)
  281.     turtle.drop()
  282.     local handle = io.open("disk/gpsStart", "w")
  283.     if handle then
  284.         handle:write('shell.run("gps", "host", '..satLoc.x..', '..satLoc.y..', '..satLoc.z..')')
  285.         handle:close()
  286.     end
  287.     local handle = io.open("/disk/label", "w")
  288.     if handle then
  289.         handle:write("gps"..satLoc.x..","..satLoc.z)
  290.         handle:close()
  291.     end
  292.     loc:up()
  293.     peripheral.call("front", "turnOn")
  294.     sleep(1)
  295.     id = peripheral.call("front", "getID")
  296.     loc:down()
  297.     turtle.select(4)
  298.     turtle.suck()
  299.     turtle.select(3)
  300.     turtle.dig()
  301.     loc:down()
  302.     loc:forward()
  303.     turtle.select(2)
  304.     turtle.placeUp()
  305.     loc:back()
  306.     loc:up()
  307.     loc:up()
  308.     peripheral.call("front", "reboot")
  309.     return id
  310. end
  311.  
  312. local towerTable = {}
  313.  
  314. if fs.exists(".towers") then
  315.     handle = io.open(".towers", "r")
  316.     if handle then
  317.         for line in handle:lines() do
  318.             local coords, ids = string.match(line, "(.-);(.*)")
  319.             towerTable[coords] = ids
  320.         end
  321.         handle:close()
  322.     end
  323. end
  324.  
  325. local loc, startLoc, towerLoc
  326.  
  327. local gpsVec = vector.new(gps.locate(0.5))
  328. if gpsVec.y > 0 then
  329.     --if gps is already available, use those coordinates.
  330.     loc = location.new(gpsVec.x, gpsVec.y, gpsVec.z, 0)
  331.     startLoc = location.new(gpsVec.x, gpsVec.y, gpsVec.z, 0)
  332.     if turtle.forward() then
  333.         local secLoc = vector.new(gps.locate())
  334.         local head = secLoc - gpsVec
  335.         loc.h = location.getOrientation(head.x, head.z)
  336.         startLoc.h = loc.h
  337.         if not turtle.back() then
  338.             loc.x, loc.y, loc.z, startLoc.x, startLoc.y, startLoc.z = secLoc.x, secLoc.y, secLoc.z, secLoc.x, secLoc.y, secLoc.z
  339.         end
  340.     end
  341. elseif #args == 4 then
  342.     if args[4] == 0 then args[4] = 4 end
  343.     loc = location.new(tonumber(args[1]), tonumber(args[2]), tonumber(args[3]), tonumber(args[4]))
  344.     startLoc = location.new(tonumber(args[1]), tonumber(args[2]), tonumber(args[3]), tonumber(args[4]))
  345. else
  346.     print("Usage:")
  347.     print("      "..fs.getName(shell.getRunningProgram()).."[x y z h]")
  348.     print("      (with gps in range)")
  349.     print("      "..fs.getName(shell.getRunningProgram()).."<x y z h>")
  350.     print("      (outside of gps range)")
  351.     return
  352. end
  353.  
  354. --determine which cell we are in.
  355. local minX = math.floor(loc.x / 372) * 372
  356. local minZ = math.floor(loc.z / 372) * 372
  357. local maxX = minX + 372
  358. local maxZ = minZ + 372
  359.  
  360. --determine closest needed tower position
  361. local neededTowers, distances = {}, {}
  362. if not towerTable[minX..","..minZ] then
  363.     table.insert(neededTowers, {minX, minZ})
  364.     table.insert(distances, math.sqrt((loc.x - minX) ^ 2 + (loc.z - minZ) ^ 2))
  365. end
  366. if not towerTable[minX..","..maxZ] then
  367.     table.insert(neededTowers, {minX, maxZ})
  368.     table.insert(distances, math.sqrt((loc.x - minX) ^ 2 + (loc.z - maxZ) ^ 2))
  369. end
  370. if not towerTable[maxX..","..minZ] then
  371.     table.insert(neededTowers, {maxX, minZ})
  372.     table.insert(distances, math.sqrt((loc.x - maxX) ^ 2 + (loc.z - minZ) ^ 2))
  373. end
  374. if not towerTable[maxX..","..maxZ] then
  375.     table.insert(neededTowers, {maxX, maxZ})
  376.     table.insert(distances, math.sqrt((loc.x - maxX) ^ 2 + (loc.z - maxZ) ^ 2))
  377. end
  378.  
  379. local distance = 9000
  380. local coords
  381. if #neededTowers > 0 then
  382.     for i=1, #neededTowers do
  383.         if distances[i] < distance then
  384.             distance = distances[i]
  385.             coords = neededTowers[i]
  386.         end
  387.     end
  388. end
  389.  
  390. if coords then
  391.     towerLoc = location.new(coords[1], 254, coords[2], 1)
  392. end
  393.  
  394. local function fuelCost(start, tower)
  395.     local dist = tower - start
  396.     return (math.abs(dist.x) + math.abs(dist.y) + math.abs(dist.z)) * 2 + 80
  397. end
  398.  
  399. local function buildCluster(clusterLoc)
  400.     local cLoc = location.new(clusterLoc.x, 254, clusterLoc.z, 2)
  401.     local wLoc = location.new(clusterLoc.x - 4, 253, clusterLoc.z, 1)
  402.     local nLoc = location.new(clusterLoc.x, 250, clusterLoc.z - 4, 2)
  403.     local eLoc = location.new(clusterLoc.x + 4, 253, clusterLoc.z, 3)
  404.     local sLoc = location.new(clusterLoc.x, 250, clusterLoc.z + 4, 4)
  405.     local idString
  406.     if turtle.getItemCount(1) >= 5 then
  407.         idString = setupSatellite(cLoc, loc)..","..setupSatellite(wLoc, loc)..","..setupSatellite(nLoc, loc)..","..setupSatellite(eLoc, loc)..","..setupSatellite(sLoc, loc)
  408.     else
  409.         idString = setupSatellite(wLoc, loc)..","..setupSatellite(nLoc, loc)..","..setupSatellite(eLoc, loc)..","..setupSatellite(sLoc, loc)
  410.     end
  411.     towerTable[cLoc.x..","..cLoc.z] = idString
  412.     local handle = io.open(".towers", "w")
  413.     if handle then
  414.         for coords, ids in pairs(towerTable) do
  415.             handle:write(coords..";"..ids.."\n")
  416.         end
  417.         handle:close()
  418.     end
  419.     moveTo(startLoc, loc)
  420.     term.setCursorPos(1, 1)
  421.     printCenter("Cluster Setup Complete")
  422.     term.setCursorPos(1, 2)
  423. end
  424.  
  425. local status
  426.  
  427. local function drawInterface()
  428.     local x, y = term.getSize()
  429.     term.clear()
  430.     term.setCursorPos(5, 1)
  431.     printCenter("GPS Satellite Setup")
  432.     term.setCursorPos(2, 3)
  433.     term.write("Starting Location")
  434.     term.setCursorPos(2, 4)
  435.     term.write("X: ")
  436.     if startLoc and startLoc.x then
  437.         term.write(tostring(startLoc.x))
  438.     end
  439.     term.setCursorPos(2, 5)
  440.     term.write("Y: ")
  441.     if startLoc and startLoc.y then
  442.         term.write(tostring(startLoc.y))
  443.     end
  444.     term.setCursorPos(2, 6)
  445.     term.write("Z: ")
  446.     if startLoc and startLoc.z then
  447.         term.write(tostring(startLoc.z))
  448.     end
  449.     term.setCursorPos(2, 7)
  450.     term.write("Facing: ")
  451.     if startLoc and startLoc.h and headingNames[startLoc.h] then
  452.         term.write(headingNames[startLoc.h])
  453.     end
  454.  
  455.     do
  456.         term.setCursorPos(22, 3)
  457.         term.write("Cluster Location")
  458.         term.setCursorPos(22, 4)
  459.         term.write("X: ")
  460.         if towerLoc and towerLoc.x then
  461.             term.write(tostring(towerLoc.x))
  462.         end
  463.         term.setCursorPos(22, 5)
  464.         term.write("Z: ")
  465.         if towerLoc and towerLoc.z then
  466.             term.write(tostring(towerLoc.z))
  467.         end
  468.         term.setCursorPos(22, 6)
  469.         if towerLoc.x == coords[1] and towerLoc.z == coords[2] then
  470.             term.setTextColor(colors.lime)
  471.         else
  472.             term.setTextColor(colors.lightGray)
  473.         end
  474.         term.write("Grid-Aligned")
  475.         term.setTextColor(colors.white)
  476.         term.setCursorPos(22, 7)
  477.         if towerLoc.x == startLoc.x and towerLoc.z == startLoc.z then
  478.             term.setTextColor(colors.lime)
  479.         else
  480.             term.setTextColor(colors.lightGray)
  481.         end
  482.         term.write("Above Current")
  483.         term.setTextColor(colors.white)
  484.     end
  485.  
  486.     do
  487.         local fuel = turtle.getFuelLevel()
  488.         local fuelRequired = fuelCost(startLoc, towerLoc)
  489.         term.setCursorPos(2, 9)
  490.         term.write("Fuel ")
  491.         term.setTextColor(colors.lightGray)
  492.         term.write("(Refuel)")
  493.         term.setTextColor(colors.white)
  494.         term.setCursorPos(2, 10)
  495.         term.write("Available: ")
  496.         term.setTextColor(fuel >= fuelRequired and colors.lime or colors.red)
  497.         term.write(tostring(fuel))
  498.         term.setTextColor(colors.white)
  499.         term.setCursorPos(2, 11)
  500.         term.write("Required: "..fuelRequired)
  501.     end
  502.  
  503.     do
  504.         term.setCursorPos(2, 13)
  505.         term.write("Status: ")
  506.         status = (turtle.getFuelLevel() >= fuelCost(startLoc, towerLoc) and turtle.getItemCount(1) >= 4 and ((turtle.getItemCount(2) >= turtle.getItemCount(1) and turtle.getItemCount(2) >= 4) or turtle.getItemCount(2) >= 5) and turtle.getItemCount(3) >= 1 and turtle.getItemCount(4) == 1)
  507.         --use status variable because external stuff needs it.
  508.         if status then
  509.             term.setBackgroundColor(colors.green)
  510.             term.write("  GO!  ")
  511.         else
  512.             term.setBackgroundColor(colors.red)
  513.             term.write(" NO-GO ")
  514.         end
  515.         term.setBackgroundColor(colors.black)
  516.     end
  517.  
  518.     do
  519.         term.setCursorPos(22, 9)
  520.         term.write("Slots")
  521.         term.setCursorPos(22, 10)
  522.         term.write("1: ")
  523.         term.setTextColor(turtle.getItemCount(1) >= 4 and colors.lime or colors.red)
  524.         term.write("4-5 Computers")
  525.         term.setTextColor(colors.white)
  526.         term.setCursorPos(22, 11)
  527.         term.write("2: ")
  528.         term.setTextColor(((turtle.getItemCount(2) >= turtle.getItemCount(1) and turtle.getItemCount(2) >= 4) or turtle.getItemCount(2) >= 5) and colors.lime or colors.red)
  529.         term.write("4-5 Modems")
  530.         term.setTextColor(colors.white)
  531.         term.setCursorPos(22, 12)
  532.         term.write("3: ")
  533.         term.setTextColor(turtle.getItemCount(3) >= 1 and colors.lime or colors.red)
  534.         term.write("1 Disk Drive")
  535.         term.setTextColor(colors.white)
  536.         term.setCursorPos(22, 13)
  537.         term.write("4: ")
  538.         term.setTextColor(turtle.getItemCount(4) == 1 and colors.lime or colors.red)
  539.         term.write("1 Disk")
  540.         term.setTextColor(colors.white)
  541.     end
  542.  
  543.     term.setCursorPos(1, y)
  544.     term.setCursorBlink(false)
  545. end
  546.  
  547. local function handleEvents()
  548.     while true do
  549.         drawInterface()
  550.         local event = {os.pullEvent()}
  551.         if event[1] == "mouse_click" then
  552.             if event[4] == 7 and event[3] >= 2 and event[3] <= 14 then
  553.                 --clicked on Facing, cycle through directions.
  554.                 startLoc.h = startLoc.h + 1
  555.                 if startLoc.h == 5 then
  556.                     startLoc.h = 1
  557.                 end
  558.                 loc.h = startLoc.h
  559.             elseif event[4] == 9 and event[3] >= 7 and event[3] <= 14 then
  560.                 --clicked Refuel
  561.                 for i = 5, 16 do
  562.                     turtle.select(i)
  563.                     turtle.refuel(64)
  564.                 end
  565.             elseif event[4] == 13 and event[3] >= 10 and event[3] <= 16 then
  566.                 --clicked go / no-go
  567.                 if status then
  568.                     writeLocalFiles()
  569.                     loc:up()
  570.                     turtle.select(3)
  571.                     turtle.placeDown()
  572.                     turtle.select(4)
  573.                     turtle.dropDown()
  574.                     sleep(1)
  575.                     writeDiskFiles()
  576.                     turtle.suckDown()
  577.                     turtle.select(3)
  578.                     turtle.digDown()
  579.                     term.clear()
  580.                     buildCluster(towerLoc)
  581.                     return
  582.                 else
  583.                     return
  584.                 end
  585.             elseif event[4] == 6 and event[3] >= 22 and event[3] <= 33 then
  586.                 --clicked grid-aligned
  587.                 towerLoc.x = coords[1]
  588.                 towerLoc.z = coords[2]
  589.             elseif event[4] == 7 and event[3] >= 22 and event[3] <= 34 then
  590.                 --clicked above current
  591.                 towerLoc.x = startLoc.x
  592.                 towerLoc.z = startLoc.z
  593.             end
  594.         end
  595.     end
  596. end
  597.  
  598. return handleEvents()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement