Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local args = {...}
- local startupFile = [[while not turtle.detectDown() do
- turtle.down()
- end
- if not os.getComputerLabel() then os.setComputerLabel("gpsSetup") end
- if fs.exists("/nsh") then
- shell.run("nsh host rom/programs/shell beacon")
- else
- shell.run("beacon")
- end
- ]]
- local beaconFile = [[local modem
- for _, side in pairs(rs.getSides()) do
- if peripheral.getType(side) == "modem" then
- modem = peripheral.wrap(side)
- break
- end
- end
- if modem then
- while true do
- modem.transmit(65532, os.getComputerID(), "beacon")
- os.startTimer(1)
- local event = {os.pullEvent()}
- if event[1] == "char" and event[2] == "q" then
- fs.delete("beacon")
- fs.delete("startup")
- return
- end
- end
- end
- ]]
- local diskStartup = [=[if turtle then
- shell.run("/startup")
- else
- if fs.exists("/disk/nsh") then
- fs.copy("/disk/nsh", "/nsh")
- end
- if fs.exists("/disk/get") then
- fs.copy("/disk/get", "/get")
- end
- if fs.exists("/disk/put") then
- fs.copy("/disk/put", "/put")
- end
- fs.copy("/disk/gpsStart", "/gpsStart")
- local file = io.open("/startup", "w")
- if file then
- if fs.exists("/nsh") then
- file:write([[shell.run("nsh host /rom/programs/shell gpsStart")]].."\n")
- else
- file:write([[shell.run("gpsStart")]])
- file:close()
- end
- end
- if fs.exists("/disk/label") then
- local file = io.open("/disk/label", "r")
- if file then
- os.setComputerLabel(file:read("*a"))
- file:close()
- end
- end
- end
- ]=]
- local function writeLocalFiles()
- local handle = io.open("startup", "w")
- if handle then
- handle:write(startupFile)
- handle:close()
- end
- local handle = io.open("beacon", "w")
- if handle then
- handle:write(beaconFile)
- handle:close()
- end
- end
- local function writeDiskFiles()
- local handle = io.open("disk/startup", "w")
- if handle then
- handle:write(diskStartup)
- handle:close()
- end
- if not fs.exists("disk/nsh") and fs.exists("nsh") then fs.copy("nsh", "disk/nsh") end
- if not fs.exists("disk/get") and fs.exists("get") then fs.copy("nsh", "disk/get") end
- if not fs.exists("disk/put") and fs.exists("put") then fs.copy("nsh", "disk/put") end
- end
- local function printCenter(text)
- text = tostring(text)
- local x, y = term.getSize()
- local xCur, yCur = term.getCursorPos()
- term.setCursorPos((x - #text) / 2 + 1, yCur)
- term.write(text)
- end
- local headingNames = {"West", "North", "East", "South"}
- local location = {}
- local Location = {
- add = function(self, o)
- return vector.new(
- self.x + o.x,
- self.y + o.y,
- self.z + o.z
- )
- end,
- sub = function(self, o)
- return vector.new(
- self.x - o.x,
- self.y - o.y,
- self.z - o.z
- )
- end,
- mul = function(self, m)
- return vector.new(
- self.x * m,
- self.y * m,
- self.z * m
- )
- end,
- div = function(self, d)
- return vector.new(
- self.x / d,
- self.y / d,
- self.z / d
- )
- end,
- left = function(self, noMove)
- self.h = self.h - 1
- if self.h < 1 then self.h = self.h + 4 end
- return noMove or turtle.turnLeft()
- end,
- right = function(self, noMove)
- self.h = self.h + 1
- if self.h > 4 then self.h = self.h - 4 end
- return noMove or turtle.turnRight()
- end,
- forward = function(self, noMove)
- if noMove or turtle then
- if noMove or turtle.forward() then
- self.x = self.x + (self.h - 2) * (self.h % 2)
- self.z = self.z + (self.h - 3) * ((self.h + 1) % 2)
- return true
- end
- end
- return false
- end,
- back = function(self, noMove)
- if turtle then
- if turtle.back() then
- self.x = self.x - (self.h - 2) * (self.h % 2)
- self.z = self.z - (self.h - 3) * ((self.h + 1) % 2)
- return true
- end
- end
- return false
- end,
- up = function(self, noMove)
- if noMove or turtle then
- if noMove or turtle.up() then
- self.y = self.y + 1
- return true
- end
- end
- return false
- end,
- down = function(self, noMove)
- if noMove or turtle then
- if noMove or turtle.down() then
- self.y = self.y - 1
- return true
- end
- end
- return false
- end,
- moveDeltas = function(self)
- return (self.h - 2) * (self.h % 2), (self.h - 3) * ((self.h + 1) % 2)
- end,
- setHeading = function(self, head)
- if not head or head < 1 or head > 4 then return nil, "Heading Not in Range" end
- while self.h ~= head do
- if (self.h + 1) % 4 == head % 4 then
- self:right()
- else
- self:left()
- end
- end
- end,
- tovector = function(self)
- if vector then
- return vector.new(
- self.x,
- self.y,
- self.z
- )
- else
- return nil
- end
- end,
- tostring = function(self)
- return self.x..","..self.y..","..self.z..","..self.h
- end,
- value = function(self)
- return self.x, self.y, self.z, self.h
- end,
- }
- local lmetatable = {
- __index = Location,
- __add = Location.add,
- __sub = Location.sub,
- __mul = Location.mul,
- __div = Location.div,
- __unm = function(l) return l:mul(-1) end,
- __tostring = function(l) return l:tostring() end,
- }
- function location.new( x, y, z, h )
- local l = {
- x = x or 0,
- y = y or 0,
- z = z or 0,
- h = h or 1
- }
- setmetatable( l, lmetatable )
- return l
- end
- function location.getOrientation(x, z)
- return ((x + math.abs(x) * 2) + (z + math.abs(z) * 3))
- end
- local function moveTo (moveLoc, loc)
- while loc.x ~= moveLoc.x or loc.z ~= moveLoc.z do
- local moveX, moveZ
- if math.abs(moveLoc.x - loc.x) > math.abs(moveLoc.z - loc.z) then
- magnitude = math.abs(moveLoc.x - loc.x)
- moveX = (moveLoc.x - loc.x) / math.abs(moveLoc.x - loc.x)
- moveZ = 0
- else
- magnitude = math.abs(moveLoc.z - loc.z)
- moveZ = (moveLoc.z - loc.z) / math.abs(moveLoc.z - loc.z)
- moveX = 0
- end
- loc:setHeading(location.getOrientation(moveX, moveZ))
- while magnitude > 0 do
- if loc:forward() then
- magnitude = magnitude - 1
- else
- loc:left()
- loc:forward()
- loc:right()
- end
- end
- end
- while loc.y ~= moveLoc.y do
- deltaY = moveLoc.y - loc.y
- if deltaY > 0 then
- loc:up()
- else
- loc:down()
- end
- end
- return loc:setHeading(moveLoc.h)
- end
- local function setupSatellite(satLoc, loc)
- moveTo(satLoc, loc)
- loc:back()
- turtle.select(1)
- turtle.place()
- loc:down()
- turtle.select(3)
- turtle.place()
- turtle.select(4)
- turtle.drop()
- local handle = io.open("disk/gpsStart", "w")
- if handle then
- handle:write('shell.run("gps", "host", '..satLoc.x..', '..satLoc.y..', '..satLoc.z..')')
- handle:close()
- end
- local handle = io.open("/disk/label", "w")
- if handle then
- handle:write("gps"..satLoc.x..","..satLoc.z)
- handle:close()
- end
- loc:up()
- peripheral.call("front", "turnOn")
- sleep(1)
- id = peripheral.call("front", "getID")
- loc:down()
- turtle.select(4)
- turtle.suck()
- turtle.select(3)
- turtle.dig()
- loc:down()
- loc:forward()
- turtle.select(2)
- turtle.placeUp()
- loc:back()
- loc:up()
- loc:up()
- peripheral.call("front", "reboot")
- return id
- end
- local towerTable = {}
- if fs.exists(".towers") then
- handle = io.open(".towers", "r")
- if handle then
- for line in handle:lines() do
- local coords, ids = string.match(line, "(.-);(.*)")
- towerTable[coords] = ids
- end
- handle:close()
- end
- end
- local loc, startLoc, towerLoc
- local gpsVec = vector.new(gps.locate(0.5))
- if gpsVec.y > 0 then
- --if gps is already available, use those coordinates.
- loc = location.new(gpsVec.x, gpsVec.y, gpsVec.z, 0)
- startLoc = location.new(gpsVec.x, gpsVec.y, gpsVec.z, 0)
- if turtle.forward() then
- local secLoc = vector.new(gps.locate())
- local head = secLoc - gpsVec
- loc.h = location.getOrientation(head.x, head.z)
- startLoc.h = loc.h
- if not turtle.back() then
- loc.x, loc.y, loc.z, startLoc.x, startLoc.y, startLoc.z = secLoc.x, secLoc.y, secLoc.z, secLoc.x, secLoc.y, secLoc.z
- end
- end
- elseif #args == 4 then
- if args[4] == 0 then args[4] = 4 end
- loc = location.new(tonumber(args[1]), tonumber(args[2]), tonumber(args[3]), tonumber(args[4]))
- startLoc = location.new(tonumber(args[1]), tonumber(args[2]), tonumber(args[3]), tonumber(args[4]))
- else
- print("Usage:")
- print(" "..fs.getName(shell.getRunningProgram()).."[x y z h]")
- print(" (with gps in range)")
- print(" "..fs.getName(shell.getRunningProgram()).."<x y z h>")
- print(" (outside of gps range)")
- return
- end
- --determine which cell we are in.
- local minX = math.floor(loc.x / 372) * 372
- local minZ = math.floor(loc.z / 372) * 372
- local maxX = minX + 372
- local maxZ = minZ + 372
- --determine closest needed tower position
- local neededTowers, distances = {}, {}
- if not towerTable[minX..","..minZ] then
- table.insert(neededTowers, {minX, minZ})
- table.insert(distances, math.sqrt((loc.x - minX) ^ 2 + (loc.z - minZ) ^ 2))
- end
- if not towerTable[minX..","..maxZ] then
- table.insert(neededTowers, {minX, maxZ})
- table.insert(distances, math.sqrt((loc.x - minX) ^ 2 + (loc.z - maxZ) ^ 2))
- end
- if not towerTable[maxX..","..minZ] then
- table.insert(neededTowers, {maxX, minZ})
- table.insert(distances, math.sqrt((loc.x - maxX) ^ 2 + (loc.z - minZ) ^ 2))
- end
- if not towerTable[maxX..","..maxZ] then
- table.insert(neededTowers, {maxX, maxZ})
- table.insert(distances, math.sqrt((loc.x - maxX) ^ 2 + (loc.z - maxZ) ^ 2))
- end
- local distance = 9000
- local coords
- if #neededTowers > 0 then
- for i=1, #neededTowers do
- if distances[i] < distance then
- distance = distances[i]
- coords = neededTowers[i]
- end
- end
- end
- if coords then
- towerLoc = location.new(coords[1], 254, coords[2], 1)
- end
- local function fuelCost(start, tower)
- local dist = tower - start
- return (math.abs(dist.x) + math.abs(dist.y) + math.abs(dist.z)) * 2 + 80
- end
- local function buildCluster(clusterLoc)
- local cLoc = location.new(clusterLoc.x, 254, clusterLoc.z, 2)
- local wLoc = location.new(clusterLoc.x - 4, 253, clusterLoc.z, 1)
- local nLoc = location.new(clusterLoc.x, 250, clusterLoc.z - 4, 2)
- local eLoc = location.new(clusterLoc.x + 4, 253, clusterLoc.z, 3)
- local sLoc = location.new(clusterLoc.x, 250, clusterLoc.z + 4, 4)
- local idString
- if turtle.getItemCount(1) >= 5 then
- idString = setupSatellite(cLoc, loc)..","..setupSatellite(wLoc, loc)..","..setupSatellite(nLoc, loc)..","..setupSatellite(eLoc, loc)..","..setupSatellite(sLoc, loc)
- else
- idString = setupSatellite(wLoc, loc)..","..setupSatellite(nLoc, loc)..","..setupSatellite(eLoc, loc)..","..setupSatellite(sLoc, loc)
- end
- towerTable[cLoc.x..","..cLoc.z] = idString
- local handle = io.open(".towers", "w")
- if handle then
- for coords, ids in pairs(towerTable) do
- handle:write(coords..";"..ids.."\n")
- end
- handle:close()
- end
- moveTo(startLoc, loc)
- term.setCursorPos(1, 1)
- printCenter("Cluster Setup Complete")
- term.setCursorPos(1, 2)
- end
- local status
- local function drawInterface()
- local x, y = term.getSize()
- term.clear()
- term.setCursorPos(5, 1)
- printCenter("GPS Satellite Setup")
- term.setCursorPos(2, 3)
- term.write("Starting Location")
- term.setCursorPos(2, 4)
- term.write("X: ")
- if startLoc and startLoc.x then
- term.write(tostring(startLoc.x))
- end
- term.setCursorPos(2, 5)
- term.write("Y: ")
- if startLoc and startLoc.y then
- term.write(tostring(startLoc.y))
- end
- term.setCursorPos(2, 6)
- term.write("Z: ")
- if startLoc and startLoc.z then
- term.write(tostring(startLoc.z))
- end
- term.setCursorPos(2, 7)
- term.write("Facing: ")
- if startLoc and startLoc.h and headingNames[startLoc.h] then
- term.write(headingNames[startLoc.h])
- end
- do
- term.setCursorPos(22, 3)
- term.write("Cluster Location")
- term.setCursorPos(22, 4)
- term.write("X: ")
- if towerLoc and towerLoc.x then
- term.write(tostring(towerLoc.x))
- end
- term.setCursorPos(22, 5)
- term.write("Z: ")
- if towerLoc and towerLoc.z then
- term.write(tostring(towerLoc.z))
- end
- term.setCursorPos(22, 6)
- if towerLoc.x == coords[1] and towerLoc.z == coords[2] then
- term.setTextColor(colors.lime)
- else
- term.setTextColor(colors.lightGray)
- end
- term.write("Grid-Aligned")
- term.setTextColor(colors.white)
- term.setCursorPos(22, 7)
- if towerLoc.x == startLoc.x and towerLoc.z == startLoc.z then
- term.setTextColor(colors.lime)
- else
- term.setTextColor(colors.lightGray)
- end
- term.write("Above Current")
- term.setTextColor(colors.white)
- end
- do
- local fuel = turtle.getFuelLevel()
- local fuelRequired = fuelCost(startLoc, towerLoc)
- term.setCursorPos(2, 9)
- term.write("Fuel ")
- term.setTextColor(colors.lightGray)
- term.write("(Refuel)")
- term.setTextColor(colors.white)
- term.setCursorPos(2, 10)
- term.write("Available: ")
- term.setTextColor(fuel >= fuelRequired and colors.lime or colors.red)
- term.write(tostring(fuel))
- term.setTextColor(colors.white)
- term.setCursorPos(2, 11)
- term.write("Required: "..fuelRequired)
- end
- do
- term.setCursorPos(2, 13)
- term.write("Status: ")
- 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)
- --use status variable because external stuff needs it.
- if status then
- term.setBackgroundColor(colors.green)
- term.write(" GO! ")
- else
- term.setBackgroundColor(colors.red)
- term.write(" NO-GO ")
- end
- term.setBackgroundColor(colors.black)
- end
- do
- term.setCursorPos(22, 9)
- term.write("Slots")
- term.setCursorPos(22, 10)
- term.write("1: ")
- term.setTextColor(turtle.getItemCount(1) >= 4 and colors.lime or colors.red)
- term.write("4-5 Computers")
- term.setTextColor(colors.white)
- term.setCursorPos(22, 11)
- term.write("2: ")
- term.setTextColor(((turtle.getItemCount(2) >= turtle.getItemCount(1) and turtle.getItemCount(2) >= 4) or turtle.getItemCount(2) >= 5) and colors.lime or colors.red)
- term.write("4-5 Modems")
- term.setTextColor(colors.white)
- term.setCursorPos(22, 12)
- term.write("3: ")
- term.setTextColor(turtle.getItemCount(3) >= 1 and colors.lime or colors.red)
- term.write("1 Disk Drive")
- term.setTextColor(colors.white)
- term.setCursorPos(22, 13)
- term.write("4: ")
- term.setTextColor(turtle.getItemCount(4) == 1 and colors.lime or colors.red)
- term.write("1 Disk")
- term.setTextColor(colors.white)
- end
- term.setCursorPos(1, y)
- term.setCursorBlink(false)
- end
- local function handleEvents()
- while true do
- drawInterface()
- local event = {os.pullEvent()}
- if event[1] == "mouse_click" then
- if event[4] == 7 and event[3] >= 2 and event[3] <= 14 then
- --clicked on Facing, cycle through directions.
- startLoc.h = startLoc.h + 1
- if startLoc.h == 5 then
- startLoc.h = 1
- end
- loc.h = startLoc.h
- elseif event[4] == 9 and event[3] >= 7 and event[3] <= 14 then
- --clicked Refuel
- for i = 5, 16 do
- turtle.select(i)
- turtle.refuel(64)
- end
- elseif event[4] == 13 and event[3] >= 10 and event[3] <= 16 then
- --clicked go / no-go
- if status then
- writeLocalFiles()
- loc:up()
- turtle.select(3)
- turtle.placeDown()
- turtle.select(4)
- turtle.dropDown()
- sleep(1)
- writeDiskFiles()
- turtle.suckDown()
- turtle.select(3)
- turtle.digDown()
- term.clear()
- buildCluster(towerLoc)
- return
- else
- return
- end
- elseif event[4] == 6 and event[3] >= 22 and event[3] <= 33 then
- --clicked grid-aligned
- towerLoc.x = coords[1]
- towerLoc.z = coords[2]
- elseif event[4] == 7 and event[3] >= 22 and event[3] <= 34 then
- --clicked above current
- towerLoc.x = startLoc.x
- towerLoc.z = startLoc.z
- end
- end
- end
- end
- return handleEvents()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement