Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- GPS Deploy 1.2 - update by Dog aka HydrantHunter
- -- http://www.computercraft.info/forums2/index.php?/topic/18830-dogs-progs-for-stargates-biolocks-and-more/
- -- pastebin: VXAyXqBv
- --
- -- This script is originally from BigSHinyToys from ComputerCraft.info
- -- Original link can be found here:
- -- http://www.computercraft.info/forums2/index.php?/topic/3088-how-to-guide-gps-global-position-system/page__p__28333#entry28333
- --
- -- Modifications included (line numbers no longer valid):
- --
- -- GPS Deploy by neonerZ v1.1
- -- http://youtube.com/neonerz
- -- http://www.computercraft.info/forums2/index.php?/topic/9528-gps-deploy-11-updated-04012014/
- --
- -- happydude11209: Line 209 - added logic to check if the server is set to no fuel mode
- -- http://www.computercraft.info/forums2/index.php?/topic/9528-gps-deploy-10/page__view__findpost__p__123411
- --
- -- kittykiller: Line 110 - Bug in the locate code if you were using an existing GPS system to deploy a new one
- -- http://www.computercraft.info/forums2/index.php?/topic/9528-gps-deploy-10/page__view__findpost__p__80323
- --
- -- Mad_Professor: Line 296 - Bug calling computers, monitors. Making people think they needed to load 4 monitors
- -- http://www.computercraft.info/forums2/index.php?/topic/9528-gps-deploy-10/page__view__findpost__p__150291
- --
- -- Dog: Too many fixes and changes to list - based on v1.1:
- -- Localized variables, reformatted table construction, eliminated duplicate
- -- and unnecessary sanity checks, reduced use of tonumber() and turtle calls,
- -- added automatic modem finding and an error for non-wireless turtles when
- -- using 'locate', automatic GPS host computer labeling (respects currently
- -- labeled computers), custom host support re-enabled, emergency
- -- return-to-start when unable to complete the job, re-ordered the program to
- -- make it more linear, converted many variables to camelCase, and more.
- -- Reasonably well tested with 100% accuracy in all tests.
- --
- -- In order to use this script you need to setup
- -- either a mining turtle, or a standard turtle
- -- Mining Turtle:
- -- Slot 1 - Fuel
- -- Slot 2 - 1 floppy disk
- -- Slot 3 - 1 disk drive
- -- Slot 4 - 4 wireless modems
- -- Slot 5 - 4 computers (labeled, unlabeled, or mixed) across
- -- slots 5, 6, 7, 8 (unlabeled computers may be stacked)
- -- Non-Mining Turtle:
- -- Slot 1 - Fuel
- -- Slot 2 - 1 floppy disk
- -- Slot 3 - 4 disk drives
- -- Slot 4 - 4 wireless modems
- -- Slot 5 - 4 computers (labeled, unlabeled, or mixed) across
- -- slots 5, 6, 7, 8 (unlabeled computers may be stacked)
- --
- -- (mining turtles will be able to reuse the same
- -- disk drive, where-as a standard turtle will leave
- -- them and deploy a separate disk drive for each
- -- GPS host)
- --
- -- Default Usage: Place the turtle where you want it
- -- deployed facing the SOUTH or 0 direction.
- -- Fill the turtle with the required materials
- -- above. Then use the command
- --
- -- gps-deploy x y z
- --
- -- Where x, y, z is the *absolute* position of the deployment
- -- turtle. By default the turtle will deploy the
- -- the GPS array at around y = 254. Add a fourth
- -- value to specify the height offset.
- -- IMPORTANT: It's crucial you use your absolute coordinates,
- -- (the ones inside the parentheses next to your relative coordinates)
- -- For Example: If F3 shows X = -6.43534 (-7) or Z = -15.542 (-16)
- -- you'd use -7 and -16 respectively. If you use -6 and -15 all coordinates
- -- that go past 0 in the opposite direction will be off by 1.)
- --
- -- Example: gps-deploy 1 1 1 20
- --
- -- Would assume the turtle's start position is
- -- x = 1, y = 1, z = 1 and will deploy the satellite
- -- array at y = 21
- --
- -- neonerZ added features
- -- Smart Refilling: Fuel should go in slot 1.
- -- If not enough fuel is available script
- -- will prompt user for more fuel and wait 30.
- -- Script will estimate how much fuel is needed
- -- and try to take only that much (in coal)
- -- Item Detection: Script will check slots 2-5
- -- for the correct quantity of items. It does
- -- *not* check if items are valid
- -- GPS Host Coordinates: The script now requires
- -- you to enter in the coordinates of the
- -- turtle before launching. This will set
- -- the GPS host computers to the correct
- -- coordinates.
- -- Satelite Array Location: The script allows
- -- the user to set an offset for the placement
- -- of the four satellites
- -- check if the script is running on a turtle
- -- (original code - modified by Dog)
- if not turtle then error("Error: Not a turtle.\n", 0) end
- -- How high up should the satellite be deployed?
- -- This is not absolute height, but relative height.
- -- This is the default value if you don't pass a
- -- value to the script. There is a check down below
- -- to make sure the absolute height isn't > 254
- local height, currentHeight, MAXHEIGHT = 254, 0, 254
- local tArgs, xCoord, yCoord, zCoord, modemSide = { ... }
- term.setBackgroundColor(colors.black)
- term.clear()
- -- determine if the turtle has a wireless modem (for 'locate' and coord verification at the end)
- for _, side in pairs({ "left", "right" }) do
- if peripheral.isPresent(side) and peripheral.getType(side) == "modem" and peripheral.call(side, "isWireless") then
- modemSide = side
- break
- end
- end
- -- Check to see if the necessary values were
- -- passed to the script
- -- confirm absolute height isn't set above 254
- if tArgs[1] == "locate" then
- if not modemSide then error("Error: Wireless turtle required for auto-location.\n", 0) end
- print("Locating GPS signal...\n")
- rednet.open(modemSide)
- xCoord, yCoord, zCoord = gps.locate(3)
- rednet.close(modemSide)
- if not xCoord then error("No GPS signal detected, please re-run manually.\n", 0) end
- if tArgs[2] and tonumber(tArgs[2]) then
- height = math.min(MAXHEIGHT - yCoord, tonumber(tArgs[2]))
- else
- height = MAXHEIGHT - yCoord
- end
- else
- if (#tArgs < 3 or #tArgs > 4) or (not tonumber(tArgs[1]) or not tonumber(tArgs[2]) or not tonumber(tArgs[3])) then
- local prog = shell.getRunningProgram()
- print("Usage:\n")
- print(prog .. " <x> <y> <z> [height]")
- print(" - or -")
- print(prog .. " locate [height]\n")
- print("Height is relative to your position.")
- print("Example: " .. prog .. " 1 1 1 20")
- print("would deploy the satellite to y = 21.\n")
- print("If you have working GPS use 'locate'")
- print("to automatically set the start coords.")
- return
- else
- xCoord = tonumber(tArgs[1])
- yCoord = tonumber(tArgs[2])
- zCoord = tonumber(tArgs[3])
- if tArgs[4] and tonumber(tArgs[4]) then
- height = math.min(MAXHEIGHT - yCoord, tonumber(tArgs[4]))
- else
- height = MAXHEIGHT - yCoord
- end
- end
- end
- -- Check if we have enough fuel
- -- we estimate the fuel usage ((height * 2) + 70) needed to
- -- complete the deployment and then see if we have enough
- -- fuel loaded. If we don't, it checks the first slot for
- -- available fuel and tries to fill up on it. If it doesn't
- -- have enough fuel in there, it prompts the user for more
- -- fuel. It allows 30 seconds for the user to add fuel
- -- (trying to refuel and verify fuel level every second)
- -- and if it doesn't get it's fill within 30 seconds
- -- it exits with a message to the user
- -- neonerZ (updated by Dog)
- local fuelHave = turtle.getFuelLevel()
- if type(fuelHave) == "string" then
- print("\n-= No-fuel mode =-\n")
- else
- local fuelRequired, fuel, coal, totalCoal = (height * 2) + 70
- if fuelHave < fuelRequired then
- turtle.select(1)
- repeat
- totalCoal = (fuelRequired - fuelHave) / 80
- coal = math.min(64, math.ceil(totalCoal))
- if not turtle.refuel(coal) then
- fuelHave = turtle.getFuelLevel()
- fuel = fuelRequired - fuelHave
- totalCoal = fuel / 80
- coal = math.min(64, math.ceil(totalCoal))
- term.clear()
- term.setCursorPos(1, 1)
- print("Insufficient fuel in slot 1.")
- for i = 30, 1, -1 do
- term.setCursorPos(1, 3)
- print("Please insert " .. tostring(fuel) .. " fuel or " .. tostring(totalCoal) .. " coal to continue. ")
- term.setCursorPos(1, 5)
- print("Waiting " .. tostring(i) .. " seconds for fuel or exiting. ")
- sleep(1)
- turtle.refuel(coal)
- fuelHave = turtle.getFuelLevel()
- if fuelHave >= fuelRequired then break end
- totalCoal = (fuelRequired - fuelHave) / 80
- coal = math.min(64, math.ceil(totalCoal))
- fuel = fuelRequired - fuelHave
- if i == 1 then
- print("\nNot enough fuel provided.\n")
- print("Please provide " .. tostring(fuel) .. " fuel or " .. tostring(totalCoal) .. " coal and try again.\n")
- return
- end
- end
- else
- fuelHave = turtle.getFuelLevel()
- end
- until fuelHave >= fuelRequired
- end
- print("\n-= Turtle Fueled =-\n")
- end
- -- check if the required quantity of items
- -- are in the appropriate spots. I'm sure
- -- there's a more elegant way of doing this.
- -- I don't believe there's a way to check if
- -- the items are correct without using compare
- -- inventory checking re-written and slotNum selection adjusted by Dog
- local err = false
- local itemTable = {
- [2] = { 1, "Please place 1 floppy disk in slot two." };
- [3] = { 1, "Please place 1 disk drive in slot three (mining turtle), or place 4 disk drives in slot three (standard turtle)." };
- [4] = { 4, "Please place 4 modems in slot four." };
- [5] = { 4, "Please place 4 computers across slots 5, 6, 7, 8. They may be labled, unlabled, or a mix of both. Unlabeled computers may be stacked." };
- }
- for i = 2, 5 do
- if turtle.getItemCount(i) < itemTable[i][1] then
- if i == 5 then
- if (turtle.getItemCount(5) + turtle.getItemCount(6) + turtle.getItemCount(7) + turtle.getItemCount(8)) < 4 then
- print(itemTable[5][2] .. "\n")
- error("Please fix the above issue(s) and restart.\n", 0)
- end
- else
- print(itemTable[i][2] .. "\n")
- error("Please fix the above issue(s) and restart.\n", 0)
- end
- end
- end
- --# Custom host program support - re-enabled by Dog
- local base
- if fs.exists("custom") then
- term.clear()
- term.setCursorPos(1, 1)
- print("Custom program detected!")
- print("Please enter base station number.\n")
- repeat
- write(" > ")
- base = tonumber(read())
- if not base then
- print("Error: Not a number.")
- print("Try again...\n")
- end
- until base
- end
- -- move functions
- local facing, currentX, currentZ = 1, xCoord, zCoord
- local cardinals, xOffset, zOffset = { "South", "West", "North", "East" }, { 0, -1, 0, 1 }, { 1, 0, -1, 0 }
- local function emergencyStop()
- local failCount = 0
- print("ABORT! Unable to complete action.")
- print("Attempting to return to origin point.")
- if currentX > xCoord then --# If east of the target then...
- if facing ~= 2 then --# if not facing west then...
- repeat --# turn until facing west
- turtle.turnRight()
- facing = (facing % 4) + 1
- until facing == 2
- end
- elseif currentX < xCoord then --# If west of the target then...
- if facing ~= 4 then --# if not facing east then...
- repeat --# turn until facing east
- turtle.turnRight()
- facing = (facing % 4) + 1
- until facing == 4
- end
- end
- if currentX ~= xCoord then
- repeat --# Move forward until currentX == xCoord
- while not turtle.forward() do
- turtle.dig()
- failCount = failCount + 1
- if failCount == 10 then error("Aborting return trip - too many obstacles.", 0) end
- end
- currentX = currentX + xOffset[facing]
- until currentX == xCoord
- end
- if currentZ > zCoord then --# If south of the target then...
- if facing ~= 3 then --# if not facing north then...
- repeat --# turn until facing north
- turtle.turnRight()
- facing = (facing % 4) + 1
- until facing == 3
- end
- elseif currentZ < zCoord then --# If north of the target then...
- if facing ~= 1 then --# if not facing south then...
- repeat --# turn until facing south
- turtle.turnRight()
- facing = (facing % 4) + 1
- until facing == 1
- end
- end
- if currentZ ~= zCoord then
- failCount = 0
- repeat --# Move forward until currentZ == zCoord
- while not turtle.forward() do
- turtle.dig()
- failCount = failCount + 1
- if failCount == 10 then error("Aborting return trip - too many obstacles.", 0) end
- end
- currentZ = currentZ + zOffset[facing]
- until currentZ == zCoord
- end
- if facing ~= 1 then --# If not facing south then...
- repeat --# turn until facing south
- turtle.turnRight()
- facing = (facing % 4) + 1
- until facing == 1
- end
- failCount = 0
- for i = 1, currentHeight do --# Now above origin point, go down until reaching the origin point
- while not turtle.down() do
- turtle.digDown()
- failCount = failCount + 1
- if failCount == 10 then error("Aborting return trip - too many obstacles.", 0) end
- end
- end
- if modemSide then
- rednet.open(modemSide)
- local gpsX, gpsY, gpsZ = gps.locate(3)
- rednet.close(modemSide)
- if gpsX then
- print((gpsX == xCoord and gpsY == yCoord and gpsZ == zCoord) and "Coordinates verified." or "Coordinates don't match.")
- else
- print("GPS array unreachable.")
- end
- end
- error("Return trip complete.\n", 0)
- end
- -- (original code - reformatted and modified by Dog)
- local failCount --# use a forward declaration so the variable doesn't have to be initialized every time a mov function is called
- local mov = {
- forward = function()
- failCount = 0
- while not turtle.forward() do
- sleep(1)
- failCount = failCount + 1
- if failCount == 5 then emergencyStop() end
- end
- currentX = currentX + xOffset[facing]
- currentZ = currentZ + zOffset[facing]
- end;
- back = function()
- failCount = 0
- while not turtle.back() do
- sleep(1)
- failCount = failCount + 1
- if failCount == 5 then emergencyStop() end
- end
- currentX = currentX - xOffset[facing]
- currentZ = currentZ - zOffset[facing]
- end;
- up = function()
- failCount = 0
- while not turtle.up() do
- sleep(1)
- failCount = failCount + 1
- if failCount == 5 then emergencyStop() end
- end
- currentHeight = currentHeight + 1
- end;
- down = function()
- failCount = 0
- while not turtle.down() do
- sleep(1)
- failCount = failCount + 1
- if failCount == 5 then emergencyStop() end
- end
- currentHeight = currentHeight - 1
- end;
- left = function()
- turtle.turnLeft()
- facing = ((facing - 2) % 4) + 1
- end;
- right = function()
- turtle.turnRight()
- facing = (facing % 4) + 1
- end;
- place = function()
- failCount = 0
- while not turtle.place() do
- sleep(1)
- failCount = failCount + 1
- if failCount == 5 then emergencyStop() end
- end
- end;
- }
- print("\nX: " .. tostring(xCoord) .. " Y: " .. tostring(yCoord) .. " Z: " .. tostring(zCoord) .. " Height: " .. tostring(height + yCoord) .. " (+" .. tostring(height) ..")\n")
- print("-= Launching =-\n")
- -- start the climb up to the correct yCoord
- for i = 1, height do
- mov.up()
- end
- -- once at the correct height, deploy GPS array
- -- this is a mixture of my own code and the
- -- original code
- -- calculate the coordinates of the 4 satellite computers
- local toYcordNS = math.min(MAXHEIGHT, yCoord + height)
- local toYcordWE = toYcordNS - 3
- local file, direction
- local coords = {
- { x = xCoord, z = zCoord + 3, y = toYcordNS };
- { x = xCoord - 3, z = zCoord, y = toYcordWE };
- { x = xCoord, z = zCoord - 3, y = toYcordNS };
- { x = xCoord + 3, z = zCoord, y = toYcordWE };
- }
- for a = 1, 4 do
- direction = cardinals[a]
- mov.forward()
- mov.forward()
- if turtle.getItemCount(5) > 0 then --# Select & place computer
- turtle.select(5)
- elseif turtle.getItemCount(6) > 0 then
- turtle.select(6)
- elseif turtle.getItemCount(7) > 0 then
- turtle.select(7)
- else
- turtle.select(8)
- end
- print("Placing " .. direction .. ".")
- mov.place()
- mov.back()
- turtle.select(4) --# Select & place modem
- mov.place()
- mov.down()
- mov.forward()
- turtle.select(3) --# Select & place disk drive
- mov.place()
- turtle.select(2) --# Select & insert floppy disk
- turtle.drop()
- -- make a custom disk that starts up the gps host application
- -- with the correct coordinates and copy it over. also
- -- makes it a startup script so the program will
- -- start back up properly after chunk reloading
- print("Configuring " .. direction .. ".")
- if fs.exists("custom") then
- fs.copy("custom","disk/custom")
- end
- file = fs.open("disk/startup", "w")
- file.write([[
- if not os.getComputerLabel() then os.setComputerLabel("GPS Host ]] .. direction .. [[ (" .. tostring(os.getComputerID()) .. ")") end
- if fs.exists("startup") and fs.exists("startup-old") then fs.delete("startup-old") end
- if fs.exists("startup") then fs.move("startup", "startup-old") end
- fs.copy("disk/install", "startup")
- fs.delete("disk/startup")
- if fs.exists("disk/custom") then
- fs.copy("disk/custom", "custom")
- fs.delete("disk/custom")
- end
- print("Sleeping for 5 seconds.")
- sleep(5)
- os.reboot()
- ]])
- file.close()
- file = fs.open("disk/install","w")
- file.write([[
- if fs.exists("custom") then
- shell.run("custom", "host", ]] .. coords[a]["x"] .. ", " .. coords[a]["y"] .. ", " .. coords[a]["z"] .. ", " .. (base or "nil") .. [[)
- else
- shell.run("gps", "host", ]] .. coords[a]["x"] .. ", " .. coords[a]["y"] .. ", " .. coords[a]["z"] .. [[)
- end
- ]])
- file.close()
- mov.left()
- mov.forward()
- mov.up()
- mov.right()
- mov.forward()
- mov.right()
- print("Activating " .. direction .. ".")
- peripheral.call("front", "turnOn")
- mov.down()
- print("Retrieving floppy & drive from " .. direction .. ".")
- turtle.select(2) --# Select slot & retreive floppy disk
- turtle.suck()
- turtle.select(3) --# Select slot & retreive floppy drive
- turtle.dig()
- mov.up()
- mov.right()
- mov.forward()
- mov.forward()
- mov.forward()
- mov.left()
- mov.forward()
- if a == 2 then
- mov.up()
- mov.up()
- mov.up()
- elseif a % 2 ~= 0 then
- mov.down()
- mov.down()
- mov.down()
- end
- end
- -- Return to starting point
- print("Returning home.\n")
- for i = 1, currentHeight do
- mov.down()
- end
- if modemSide then
- rednet.open(modemSide)
- local gpsX, gpsY, gpsZ = gps.locate(3)
- rednet.close(modemSide)
- if gpsX then
- print((gpsX == xCoord and gpsY == yCoord and gpsZ == zCoord) and "Success! Coordinates verified.\n" or "Failure. Coordinates don't match.\n")
- else
- print("GPS array unreachable. Unable to verify installation.\n")
- end
- else
- print("Finished.\n")
- end
Add Comment
Please, Sign In to add comment