Ranger1230

GPSMinningTurtle

Feb 4th, 2014
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.43 KB | None | 0 0
  1. --This dynamically built off of the save file so in theory
  2. --It doesn't need to be fully declared but this helps make
  3. --it a bit more clear.
  4. local state = {
  5.     startingCoords = {
  6.         x = nil,
  7.         y = nil,
  8.         z = nil
  9.     },
  10.     currentCoords = {
  11.         x = nil,
  12.         y = nil,
  13.         z = nil
  14.     },
  15.     facing = nil,
  16.     desiredDiameter = nil,
  17.     useGPS = true
  18. }
  19. local saveFileName = "gpsState"
  20.  
  21. local helpers = {
  22.    
  23.     split = function(pString, pPattern)
  24.        local Table = {}  -- NOTE: use {n = 0} in Lua-5.0
  25.        local fpat = "(.-)" .. pPattern
  26.        local last_end = 1
  27.        local s, e, cap = pString:find(fpat, 1)
  28.        while s do
  29.             if s ~= 1 or cap ~= "" then
  30.                 table.insert(Table,cap)
  31.             end
  32.             last_end = e+1
  33.             s, e, cap = pString:find(fpat, last_end)
  34.        end
  35.        if last_end <= #pString then
  36.             cap = pString:sub(last_end)
  37.             table.insert(Table, cap)
  38.        end
  39.        return Table
  40.     end,
  41.  
  42.     getInput = function(message)
  43.         local input
  44.         print(message)
  45.         input = read()
  46.         return input
  47.     end,
  48.  
  49.     whereAmI = function()
  50.         print("The turtle is at is x="..state.currentCoords.x..", y="..state.currentCoords.y..", z="..state.currentCoords.z)
  51.     end,
  52.    
  53.     printObject = function(self, key, value)
  54.         if type(value) == "table" then
  55.             for subKey,subValue in pairs(value) do
  56.                 print(key.."={")
  57.                 self.printObject(self, subKey, subValue)
  58.                 print("}")
  59.             end
  60.         else
  61.             print(key.."="..tostring(value))
  62.         end
  63.     end,
  64.    
  65.     clearScreen = function()
  66.         term.clear()
  67.         term.setCursorPos(1,1)
  68.     end,
  69.    
  70.     getInputAndClearScreen = function(message)
  71.         local input
  72.         print(message)
  73.         input = read()
  74.         term.clear()
  75.         term.setCursorPos(1,1)
  76.         return input
  77.     end,
  78.    
  79.     getCoordinate = function(message, self)
  80.         local input
  81.        
  82.         if self == nil then
  83.             error("getCoordinate is missing the argument helpers.")
  84.         end
  85.        
  86.         print(message)
  87.         input = read()
  88.         if tonumber(input) == nil then
  89.             print("That is not a number.")
  90.             --Reflection to get a valid number
  91.             return self.getCoordinate(message, self)
  92.         else
  93.             return input
  94.         end
  95.     end,
  96.    
  97.     saveObjectToFileAsJson = function(fileName, object)
  98.         local file
  99.         if fs.exists("json") ~= true then
  100.             error("you do not have the json function. please enter 'pastebin get 4nRg9CHU json'")
  101.         end
  102.         if json == nil then
  103.             os.loadAPI("json")
  104.         end
  105.         file = fs.open(fileName, "w")
  106.         file.writeLine(json.encode(object))
  107.         file.close()
  108.     end,
  109.    
  110.     manualStartingPointEnter = function(self)
  111.         local input
  112.        
  113.         if self == nil then
  114.             error("manualStartingPointEnter is missing the argument helpers.")
  115.         end
  116.        
  117.         self.clearScreen()
  118.         state.startingCoords.x = self.getCoordinate("Please enter the starting x coordinate.", self)
  119.         state.currentCoords.x = state.startingCoords.x
  120.         self.clearScreen()
  121.         state.startingCoords.y = self.getCoordinate("Please enter the starting y coordinate.", self)
  122.         state.currentCoords.y = state.startingCoords.y
  123.         self.clearScreen()
  124.         state.startingCoords.z = self.getCoordinate("Please enter the starting z coordinate.", self)
  125.         state.currentCoords.z = state.startingCoords.z
  126.         self.clearScreen()
  127.        
  128.         self.whereAmI()
  129.        
  130.         input = self.getInput("Is the correct(yes/no)?")
  131.         if input ~= "yes" then
  132.             if input ~= "y" then
  133.                 self.manualStartingPointEnter()
  134.             end
  135.         end
  136.     end,
  137.    
  138.     loadJsonObjectFromFile = function(fileName, object)
  139.         local file, result, line
  140.         if fs.exists("json") ~= true then
  141.             error("you do not have the json function. please enter 'pastebin get 4nRg9CHU json'")
  142.         end
  143.         if json == nil then
  144.             os.loadAPI("json")
  145.         end
  146.         result = json.decodeFromFile(fileName)
  147.         for key,value in pairs(result) do
  148.             object[key] = value
  149.         end
  150.     end,
  151.    
  152.     formatState = function()
  153.         if (state.useGPS ~= nil) and (state.useGPS == 1) then
  154.             state.useGPS = true
  155.         elseif (state.useGPS ~= nil) then
  156.             state.useGPS = false
  157.         end
  158.         if state.desiredDiameter ~= nil then
  159.             state.desiredDiameter = tonumber(state.desiredDiameter)
  160.         end
  161.     end,
  162.    
  163.     loadCurrentLocation = function()
  164.         local line
  165.         local file = fs.open("CurrentLocation", "r")
  166.        
  167.         line = file.readLine(readLine)
  168.         print("parseString in loadCurrentLocation")
  169.         self.parseString(line, self, state)
  170.        
  171.         file.close()
  172.     end,
  173.  
  174.     openRednetConnection = function()
  175.         local sides = {"left","right","front","back","bottom","top"}
  176.  
  177.         for i=1, #sides do
  178.             if pcall(rednet.open, sides[i]) then
  179.                 return
  180.             end
  181.         end
  182.         error("could not find a wireless modem")
  183.     end,
  184.  
  185.     closeRednetConnection = function()
  186.         local sides = {"left","right","front","back","bottom","top"}
  187.        
  188.         for i=1, #sides do
  189.             if rednet.isOpen(sides[i]) then
  190.                 rednet.close(sides[i])
  191.                 return
  192.             end
  193.         end
  194.         error("could not find a open connection")
  195.     end,
  196.  
  197.     objectContains = function(array, valueToCheck)
  198.         for key,value in pairs(array) do
  199.             if valueToCheck == value then
  200.                 return true
  201.             end
  202.         end
  203.         return false
  204.     end,
  205.    
  206.     tableLength = function(tableObject)
  207.         local count = 0
  208.        
  209.         for key,value in pairs(tableObject) do
  210.             count = count + 1
  211.         end
  212.         return count
  213.     end
  214. }
  215.  
  216. local smartTurtleClass = {
  217.     run = function(self)
  218.         error("Not implemented")
  219.     end
  220. }
  221.  
  222. local worldEaterTurtleClass = {
  223.  
  224.     run = function(self)
  225.         local command, commanderID, distence, loop
  226.         loop = true
  227.         helpers.openRednetConnection()
  228.        
  229.         while loop do
  230.        
  231.             rednet.broadcast("ready and waiting")
  232.            
  233.             print("waiting for command")
  234.            
  235.             commanderID, command, distence = self.reciveCommand()
  236.            
  237.             if command == "dig" then
  238.                 print("begin digging down")
  239.             elseif command == "refuel" then
  240.                 print("Check fuel level and refill if needed")
  241.             elseif command == "done" then
  242.                 rednet.send(commanderID, "Shuttingdown")
  243.                 loop = false
  244.             end
  245.        
  246.         end
  247.        
  248.         helpers.closeRednetConnection()
  249.     end,
  250.    
  251.     reciveCommand = function()
  252.         local commanderID, command, distence, loop
  253.         loop = true
  254.        
  255.         while loop do
  256.             commanderID, command, distence = rednet.receive()
  257.            
  258.             if string.find(command, "Command:") == 1 then
  259.                 loop = false
  260.                 return commanderID, string.sub(command, 9), distence
  261.             end
  262.         end
  263.     end,
  264.    
  265.     goDown = function(self)
  266.         local running = true
  267.        
  268.         while running do
  269.             turtle.dig()
  270.             turtle.digDown()
  271.             if turtle.down() == false then
  272.                 turtle.attackDown()
  273.             end
  274.         end
  275.         state.currentCoords.y = state.currentCoords.y - 1
  276.        
  277.         helpers.saveState()
  278.        
  279.         if state.currentCoords.y < 5 then
  280.             running = false
  281.         end
  282.     end,
  283.    
  284.     goUp = function(self)
  285.         local running = true
  286.        
  287.         while running do
  288.             turtle.dig()
  289.             turtle.digUp()
  290.             if turtle.up() == false then
  291.                 turtle.attackUp()
  292.             end
  293.         end
  294.         state.currentCoords.y = state.currentCoords.y + 1
  295.        
  296.         helpers.saveState()
  297.        
  298.         if state.currentCoords.y == state.startingCoords.y then
  299.             running = false
  300.         end
  301.     end
  302. }
  303.  
  304. local masterWorldeaterComputerClass = {
  305. --ToDo:
  306. --      Master listens to chat for:
  307. --          ServerShutdown 30 min or less
  308. --              Finish round and stop
  309. --          ServerShutDown 1 min or less
  310. --              Emergency stop
  311. --                  Means the turtles will have to be listening to the master while running.
  312. --          Ranger1230 logged out
  313. --              Finish round and stop.
  314. --          Worldeater stop!
  315. --              Respond with "Finishing round sorry if I was lagging the server"
  316. --              If Sirloin says it finish round and pick up all chunkloaders
  317. --          If Sirloin says "Worldeater stop now!
  318. --              Emergency stop and pick up all chunkloaders
  319. --      Master waits for all slaves to finish around before:
  320. --          Tells slaves to refuel if needed.
  321. --          Tells slaves to begin next round.
  322.     runningLoop = true,
  323.    
  324.     connections = {},
  325.    
  326.     run = function(self)
  327.         helpers.openRednetConnection()
  328.        
  329.         print("Gathering connections")
  330.         parallel.waitForAny(self.waitForInput, function() self.gatherConnections(self) end)
  331.         print("Run master computer")
  332.        
  333.         --Use a parallel to listen to game chat for command and run the mining program
  334.        
  335.         self.eatTheWorld(self)
  336.        
  337.         helpers.closeRednetConnection()
  338.     end,
  339.    
  340.     eatTheWorld = function(self)
  341.         self.sendCommand(self, "done")
  342.     end,
  343.    
  344.     sendCommand = function(self, command)
  345.         for turtleID,value in pairs(self.connections) do
  346.             rednet.send(turtleID, "Command:"..command, true)
  347.         end
  348.     end,
  349.    
  350.     waitForInput = function()
  351.         local input
  352.        
  353.         input = read()
  354.         helpers.clearScreen()
  355.         print("input received")
  356.     end,
  357.    
  358.     gatherConnections = function(self)
  359.         local senderId, message, distance
  360.        
  361.         while true do
  362.             senderId, message, distance = rednet.receive(10)
  363.             if (message == "ready and waiting") and (distance < 1000) then
  364.                 self.connections[senderId] = true
  365.                 helpers.clearScreen()
  366.                 print("There are "..(helpers.tableLength(self.connections)).." turtles connected. Hit enter to run.")
  367.             end
  368.         end
  369.     end
  370. }
  371.  
  372. function getDiameter()
  373.     local input = helpers.getInput("What diameter would you like to harvest?")
  374.     diameter = tonumber(input)
  375.     if diameter == nil then
  376.         if input == "worldeater" then
  377.             print("Entering Worldeater mode.")
  378.             state.facing = nil
  379.             state.diameter = nil
  380.             state.currentCoords.x = state.startingCoords.x
  381.             state.currentCoords.y = state.startingCoords.y
  382.             state.currentCoords.z = state.startingCoords.z
  383.         else
  384.             print("Please enter a number.")
  385.             getDiameter()
  386.         end
  387.     end
  388. end
  389.  
  390. function runTurtle()
  391.     if fs.exists(saveFileName) then
  392.         helpers.loadJsonObjectFromFile(saveFileName, state)
  393.     else
  394.         x, y, z = gps.locate(5)
  395.        
  396.         if (x == nil) or (y == nil) or (z == nil) then
  397.             print("No gps computer was detected. please enter current coordinates manually.")
  398.             helpers.manualStartingPointEnter(helpers)
  399.             state.useGPS = false
  400.         end
  401.        
  402.         state.facing = 0
  403.         getDiameter()
  404.         helpers.saveObjectToFileAsJson(saveFileName, state)
  405.     end
  406.    
  407.     if state.useGPS == true then
  408.         worldEaterTurtleClass.run(worldEaterTurtleClass)
  409.     else
  410.         smartTurtleClass.run(smartTurtleClass)
  411.     end
  412. end
  413.  
  414. function runGpsComputer()
  415.     if fs.exists(saveFileName) then
  416.         helpers.loadJsonObjectFromFile(saveFileName, state)
  417.     else
  418.         helpers.manualStartingPointEnter(helpers)
  419.         state.diameter = 0
  420.         state.facing = 0
  421.         helpers.saveObjectToFileAsJson(saveFileName, state)
  422.     end
  423.     shell.run("gps","host",state.startingCoords.x,state.startingCoords.y,state.startingCoords.z)
  424. end
  425.  
  426. if turtle == nil then
  427.     local loop, input
  428.     loop = true
  429.    
  430.     while loop do
  431.         input = helpers.getInput("Is this a GPS provider computer? (yes/no)")
  432.         if (input == "yes") or (input == "y") then
  433.             loop = false
  434.             runGpsComputer()
  435.         elseif (input == "no") or (input == "n") then
  436.             loop = false
  437.             masterWorldeaterComputerClass.run(masterWorldeaterComputerClass)
  438.         end
  439.     end
  440.    
  441. else
  442.     runTurtle()
  443. end
Advertisement
Add Comment
Please, Sign In to add comment