Guest User

quarry 3.2.0 beta 3

a guest
Aug 29th, 2013
773
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 32.54 KB | None | 0 0
  1. --[[
  2. Version 3.2.0
  3. Recent Changes:
  4. 1. Now has session persistence! Just type "quarry -restore"
  5.    and your turtle will pick up where it left off
  6. 2. New Argument: startY to help stop it from getting stuck on those nasty sheep!
  7. 3. Most directional functions take care of invert. Exception is turtle.detect
  8. ]]
  9. --[[ToDo:
  10. 1. Actually get the rednet send back and forth to work
  11. 3. Send basic commands from receiver program e.g. Stop
  12. 6. Add in rednet stuff
  13. 7. Massive update for rednet program
  14. ]]
  15. --Defining things
  16. _G.civilTable = {}; civilTable = nil; setmetatable(civilTable, {__index = _G}); setfenv(1,civilTable)
  17. -------Defaults for Arguments----------
  18. --Arguments assignable by text
  19. x,y,z = 3,3,3 --These are just in case tonumber fails
  20. inverted = false --False goes from top down, true goes from bottom up [Default false]
  21. rednetEnabled = false --Default rednet on or off  [Default false]
  22. --Arguments assignable by tArgs
  23. dropSide = "front" --Side it will eject to when full or done [Default "front"]
  24. careAboutResources = true --Will not stop mining once inventory full if false [Default true]
  25. doCheckFuel = true --Perform fuel check [Default true]
  26. doRefuel = false --Whenever it comes to start location will attempt to refuel from inventory [Default false]
  27. invCheckFreq = 10 --Will check for inventory full every <-- moved spaces [Default 10]
  28. keepOpen = 1 --How many inventory slots it will attempt to keep open at all times [Default 1]
  29. fuelSafety = "moderate" --How much fuel it will ask for: safe, moderate, and loose [Default moderate]
  30. saveFile = "Civil_Quarry_Restore" --Where it saves restore data [Default "Civil_Quarry_Restore"]
  31. doBackup = true --If it will keep backups for session persistence [Default true]
  32. gpsEnabled = false -- If option is enabled, will attempt to find position via GPS api
  33. gpsTimeout = 3 --The number of seconds the program will wait to get GPS coords
  34. --Standard number slots for fuel (you shouldn't care)
  35. fuelTable = { --Will add in this amount of fuel to requirement.
  36. safe = 1000,
  37. moderate = 200,
  38. loose = 0 } --Default 1000, 200, 0
  39. --Standard rednet channels
  40. channels = {
  41. send = os.getComputerID()  ,
  42. receive = os.getComputerID() + 100 ,
  43. confirm = "Confirm"
  44. }
  45.  
  46. local help_paragraph = [[
  47. -DEFAULT: This will ignore all arguments and prompts and use defaults
  48. -vanilla: This will ignore all arguments except for dimensions
  49. -dim: [num] [num] [num] This sets the dimensions of the quarry
  50. -invert: [t/f] This sets whether invert is true or false
  51. -rednet: [t/f] This sets whether it will attempt to make a rednet connection
  52. -sendChannel: [num] This sets the channel the turtle will attempt to send on
  53. -receiveChannel: [num] This sets the channel the turtle will attempt to receive on
  54. -doRefuel: Changes whether or not the turtle will refuel itself with coal when fuel is low (opposite of written config)
  55. -doCheckFuel: Changes whether or not the turtle will check its fuel level before running (opposite of written config)
  56. -chest: [chest side] Changes what side turtle will output to
  57. -startY: [num] Tells the turtle what y coordinate it starts at, to make bedrock checking more accurate (hopefully)
  58. -keepOpen: [num] How many slots of the inventory turtle will try to keep open (Will then auto-empty)
  59. -invCheckFreq: [num] How many blocks before full inventory checks
  60. -saveFile: [word] Changes where the turtle saves its backup to.
  61. -doBackup: [t/f] Whether or not the turtle will backup its current position to a file.
  62. -restore: Turtle will check for a save file. If found will ignore all other arguments.
  63. -fuelSafety: [safe/moderate/loose] How much extra fuel the turtle will request at startup
  64. -GPS: [t/f] If true, will attempt to connect to GPS and record its location from that.
  65. Examples [1]:
  66.  The minimum amount necessary to start a turtle automatically would be one of these two
  67.  ---------
  68.  quarry -dim 3 3 3 -invert false -rednet false
  69.  ---------
  70.  quarry -dim 3 3 3 -vanilla
  71.  ---------
  72.  or, if you actually wanted a 3x3x3 then
  73.  ---------
  74.  quarry -DEFAULT
  75. Examples [2]:
  76.  If you wanted start a quarry that has
  77.  rednet on channels 500 and 501, outputs
  78.  to a chest below itself, is inverted,
  79.  and has the dimesions 5x5x21, then here
  80.  is what you would type: (Remember that
  81.  order does not matter)
  82.  ----------
  83.  quarry -receiveChannel 501 -sendChannel 500 -invert true -dim 5 5 21 -chest bottom -rednet true
  84. Examples [2] (cont.):
  85.  Now, this may be very long, but it is meant for people who want to make automated quarries with
  86.  the same settings every time (or with variable setting)
  87. Examples [3]:
  88.  If you are playing softcore then you
  89.  can do
  90.  ---------
  91.  quarry -doCheckFuel false
  92.  ---------
  93.  Followed by any other arguments
  94. Tips:
  95.  You don't actually have to type out "false" or "true" if you don't want. It actaully just checks if the first
  96.  letter is "t", so you (usually) don't have to put anything at all. Putting the whole word just helps with clarity
  97. Internal Config:
  98. At the top of the program, right below the changelog is a written config. Anything not specified by arguments
  99. will be taken from here. If you have a quarry setup you use a lot, you could just edit the config and then
  100. type in the following:
  101. ----------
  102. quarry -DEFAULT
  103. ]]
  104.  
  105. --Parsing help for display
  106. --[[The way the help table works:
  107. All help indexes are numbered. There is a help[i].title that contains the title,
  108. and the other lines are in help[i][1] - help[i][#help[i] ]
  109. Different lines (e.g. other than first) start with a space.
  110. As of now, the words are not wrapped, fix that later]]
  111. local help = {}
  112. local i = 0
  113. local titlePattern = ".-%:" --Find the beginning of the line, then characters, then a ":"
  114. local textPattern = "%:.+" --Find a ":", then characters until the end of the line
  115. for a in help_paragraph:gmatch("\n?.-\n") do --Matches in between newlines
  116. local current = string.sub(a,1,-2).."" --Concatenate Trick
  117. if string.sub(current,1,1) ~= " " then
  118. i = i + 1
  119. help[i] = {}
  120. help[i].title = string.sub(string.match(current, titlePattern),1,-2)..""
  121. help[i][1] = string.sub(string.match(current,textPattern) or " ",3,-1)
  122. elseif string.sub(current,1,1) == " " then
  123. table.insert(help[i], string.sub(current,2, -1).."")
  124. end
  125. end
  126.  
  127.  
  128. local supportsRednet = (peripheral.wrap("right") ~= nil)
  129.  
  130. local tArgs = {...}
  131. --You don't care about these
  132.       xPos,yPos,zPos,facing,percent,mined,moved,relxPos, rowCheck, connected, isInPath, layersDone, attacked, endRow, startY
  133.     = 0,   1,   1,   0,     0,      0,    0,    1,       "right",  false,     true,     1,          0,        0,      0
  134.  
  135. local totals = {cobble = 0, fuel = 0, other = 0} -- Total for display (cannot go inside function)
  136. local function count() --Done any time inventory dropped and at end
  137. slot = {}        --1: Cobble 2: Fuel 3:Other
  138. for i=1, 16 do   --[1] is type, [2] is number
  139. slot[i] = {}
  140. slot[i][2] = turtle.getItemCount(i)
  141. end
  142. slot[1][1] = 1   -- = Assumes Cobble/Main
  143. for i=1, 16 do   --Cobble Check
  144. turtle.select(i)
  145. if turtle.compareTo(1)  then
  146. slot[i][1] = 1
  147. totals.cobble = totals.cobble + slot[i][2]
  148. elseif turtle.refuel(0) then
  149. slot[i][1] = 2
  150. totals.fuel = totals.fuel + slot[i][2]
  151. else
  152. slot[i][1] = 3
  153. totals.other = totals.other + slot[i][2]
  154. end
  155. end
  156. turtle.select(1)
  157. end
  158. local function checkFuel()
  159. return turtle.getFuelLevel()
  160. end
  161.  
  162.  -----------------------------------------------------------------
  163. --Input Phase
  164. local function screen(xPos,yPos)
  165. xPos, yPos = xPos or 1, yPos or 1
  166. term.setCursorPos(xPos,yPos); term.clear(); end
  167. local function screenLine(xPos,yPos)
  168. term.setCursorPos(xPos,yPos); term.clearLine(); end
  169.  
  170. screen(1,1)
  171. print("----- Welcome to Quarry! -----")
  172. print("")
  173.  
  174. --Hmm, this section seems like I was just playing with different text formatting options...
  175. local sides = {top = "top", right = "right", left = "left", bottom = "bottom", front = "front"} --Used to whitelist sides
  176. local errorT = {num = "Numbers not recognized", zero = "Variable is out of range", word = "String failed assertion" }
  177. local changedT = {}
  178. changedT.new = function(key, value) changedT[#changedT+1] = {[key] = value} end
  179. changedT.getPair = function(i) for a, b in pairs(changedT[i]) do return a, b end end
  180. local function capitalize(text) return (string.upper(string.sub(text,1,1))..string.sub(text,2,-1)) end
  181. local function assert(condition, message, section) section = section or "[Blank]"; if condition then return condition else error("Error: "..message.."\nin section "..section, 0) end end
  182. local function checkNum(number, section) return assert(tonumber(number),errorT.num, section) end
  183. tArgs.checkStart = function(num) tArgs[tArgs[num]] = num end
  184. for i=1, #tArgs do tArgs.checkStart(i) end
  185.  
  186. --Check if it is a turtle
  187. if not turtle then
  188.   print("This is not a turtle, you must be looking for the \"Companion Rednet Program\" \nCheck My forum thread for that")
  189.   print("Press 'q' to quit, or any other key to start help ")
  190.   if ({os.pullEvent("char")})[2] ~= "q" then tArgs.help = true else error("",0) end
  191. end
  192.  
  193.  
  194. if tArgs["help"] or tArgs["-help"] or tArgs["-?"] or tArgs["?"] then
  195. print("You have selected help, press any key to continue"); print("Use arrow keys to naviate, q to quit"); os.pullEvent("key")
  196. local pos = 1
  197. local key = 0
  198. while pos <= #help and key ~= keys.q do
  199. if pos < 1 then pos = 1 end
  200. screen(1,1)
  201. print(help[pos].title)
  202. for a=1, #help[pos] do print(help[pos][a]) end
  203. repeat
  204. _, key = os.pullEvent("key")
  205. until key == 200 or key == 208 or key == keys.q
  206. if key == 200 then pos = pos - 1 end
  207. if key == 208 then pos = pos + 1 end
  208. end
  209. error("",0)
  210. end
  211.  
  212.  
  213. --Saving
  214. if tArgs["doBackup"] then doBackup = (string.lower(string.sub(tArgs[tArgs["doBackup"]+1],1,1)) ~= "f") end
  215. if tArgs["saveFile"] then saveFile = tArgs[tArgs["saveFile"]+1] or saveFile end
  216.  
  217. local restoreFound = false
  218. if tArgs["-restore"] or tArgs["-resume"] then
  219. restoreFound = fs.exists(saveFile)
  220. if restoreFound then
  221. os.run(getfenv(1),saveFile)
  222. if gpsEnabled then --If it had saved gps coordinates
  223.   print("Found GPS Start Coordinates")
  224.   local currLoc = {gps.locate(3)}
  225.   if #currLoc > 0 and #gpsStartPos > 0 and #gpsSecondPos > 0 then --Cover all the different positions I'm using
  226.     print("GPS Position Successfully Read")
  227.     if currLoc[1] == gpsStartPos[1] and currLoc[3] == gpsStartPos[3] then --X coord, y coord, z coord in that order
  228.       xPos, yPos, zPos = 0,1,1
  229.       if facing ~= 0 then turnTo(0) end
  230.       print("Is at start")
  231.     else
  232.       if inverted then --yPos setting
  233.       ------------------------------------------------FIX THIS
  234.       end
  235.       local function copyTable(tab) local toRet = {}; for a, b in pairs(tab) do toRet[a] = b end; return toRet end
  236.       local a, b = copyTable(gpsStartPos), copyTable(gpsSecondPos) --For convenience
  237.       if b[3] - a[3] == -1 then--If went north (-Z)
  238.         a[1] = a[1] - 1 --Shift x one to west to create a "zero"
  239.         xPos, zPos = -currLoc[3] + a[3], currLoc[1] + -a[1]
  240.       elseif b[1] - a[1] == 1 then--If went east (+X)
  241.         a[3] = a[3] - 1 --Shift z up one to north to create a "zero"
  242.         xPos, zPos = currLoc[1] + -a[1], currLoc[3] + -a[3]
  243.       elseif b[3] - a[3] == 1 then--If went south (+Z)
  244.         a[1] = a[1] + 1 --Shift x one to east to create a "zero"
  245.         xPos, zPos = currLoc[3] + a[3], -currLoc[1] + a[3]
  246.       elseif b[1] - a[1] == -1 then--If went west (-X)
  247.         a[3] = a[3] + 1 --Shift z down one to south to create a "zero"
  248.         xPos, zPos = -currLoc[1] + a[1], -currLoc[3] + a[3]
  249.       else
  250.         print("Improper Coordinates")
  251.         print("GPS Locate Failed, Using Standard Methods")        ----Maybe clean this up a bit to use flags instead.
  252.       end  
  253.     end
  254.     ----------------------------------------------------------------------------------------------------------------
  255.     --FIGURE OUT WHAT IS GOING WRONG. RIGHT NOW THE XPOS IS OFF BY ONE AND ZPOS IS JUST WIERD. FIX IT
  256.     --Plan: Have a offset a one to left to use as a zero
  257.     --Plan implemented. Testing in progress...
  258.     --First round of testing done: It seems to be able to get its position perfectly the first time, but second restart, z is off by one. Possibly local
  259.     -- isn't working and it is just modifying the global table, offsetting it by one more every time so it thinks it is further away.
  260.     -- Testing was done in two perpendicular directions.
  261.     --Plan: Seems to be working, just going to copy tables values
  262.     ----------------------------------------------------------------------------------------------------------------
  263.     print("X Pos: ",xPos)
  264.     print("Y Pos: ",yPos)
  265.     print("Z Pos: ",zPos)
  266.     print("Facing: ",facing)
  267.   else
  268.     print("GPS Locate Failed, Using Standard Methods")
  269.   end    
  270. print("Restore File read successfully. Starting in 3"); sleep(3)
  271. end
  272. end
  273. end
  274.  
  275. if not (tArgs["-DEFAULT"] or restoreFound) then
  276.   --Just a note, the whole error checking section here was more of an
  277.   --experiment than anything else. If its ever changed in the future,
  278.   --it would probably be for the better.
  279. local section = "Dimensions"
  280. --Dimesnions
  281. if tArgs["-dim"] then local num = tArgs["-dim"];
  282. x = checkNum(tArgs[num + 1],section); z = checkNum(tArgs[num + 2],section); y = checkNum(tArgs[num + 3],section)
  283. else
  284. print("What dimensions?")
  285. print("")
  286. --This will protect from negatives, letters, and decimals
  287. term.write("Length: ")
  288. x = math.floor(math.abs(tonumber(io.read()) or x))
  289. term.write("Width: ")
  290. z = math.floor(math.abs(tonumber(io.read()) or z))
  291. term.write("Height: ")
  292. y = math.floor(math.abs(tonumber(io.read()) or y))
  293. end
  294. changedT.new("x",x); changedT.new("z",z); changedT.new("y",y)
  295. assert(x~=0, errorT.zero, section); assert(z~=0, errorT.zero, section); assert(y~=0, errorT.zero, section)
  296. assert(not(x == 1 and y == 1 and z == 1) ,"1, 1, 1 dosen't work well at all, try again", section)
  297. if not tArgs["-vanilla"] then
  298. --Invert
  299. if tArgs["-invert"] then
  300. inverted = (string.lower(string.sub(tArgs[tArgs["-invert"]+1] or "",1,1)) == "t") else
  301. term.write("Inverted? ")
  302. inverted = (string.lower(string.sub(io.read(),1,1)) == "y")
  303. end
  304. changedT.new("Inverted", inverted)
  305. --Rednet
  306. if supportsRednet then
  307. if tArgs["-rednet"] then
  308. rednetEnabled = (string.lower(string.sub(tArgs[tArgs["-rednet"]+1] or "",1,1)) == "t")
  309. else term.write("Rednet? "); rednetEnabled = (string.lower(string.sub(io.read(),1,1)) == "y")
  310. if tArgs["-GPS"] and not restoreFound then
  311. gpsStartPos = {gps.locate(gpsTimeout)} --Stores position in array
  312. gpsEnabled = #gpsStartPos > 0 --Checks if location received properly
  313. changedT.new("GPS Location Services", gpsEnabled)
  314. end
  315. changedT.new("Rednet Enabled", rednetEnabled)
  316. end
  317. if tArgs["-sendChannel"] then
  318. channels.send = assert(tonumber(tArgs[tArgs["-sendChannel"]+1]), errorT.num)
  319. assert(channels.send > 0 and channels.send < 65535, errorT.zero)
  320. changedT.new("Send Channel",channels.send) end
  321. if tArgs["-receiveChannel"] then
  322. channels.receive = assert(tonumber(tArgs[tArgs["-receiveChannel"]+1]), errorT.num)
  323. assert(channels.receive > 0 and channels.receive < 65535 and channels.receive ~= channels.send, errorT.zero)
  324. changedT.new("Receive Channel",channels.receive) end
  325. end
  326. --Fuel
  327. if tArgs["-doRefuel"] then doRefuel = not doRefuel; changedT.new("Do Refuel",doRefuel) end
  328. if turtle.getFuelLevel() == "unlimited" then
  329.   doCheckFuel = false
  330. else
  331.   if tArgs["-doCheckFuel"] then
  332.   doCheckFuel = (string.lower(string.sub(tArgs[tArgs["-doCheckFuel"]+1] or "",1,1)) == "t"); changedT.new("Do Check Fuel", doCheckFuel) end
  333. end
  334. if tArgs["-chest"] then
  335. dropSide = sides[tArgs[tArgs["-chest"]+1]] or dropSide; changedT.new("Chest Side",dropSide) end
  336. if tArgs["-fuelSafety"] then local loc = tArgs[tArgs["-fuelSafety"]+1]
  337.   if fuelTable[loc] then
  338.     fuelSafety = loc; changedT.new("Fuel Check Safety", fuelSafety)
  339.   end
  340. end
  341. --Misc
  342. if tArgs["-startY"] then
  343. startY = math.abs(math.floor(checkNum(tArgs[tArgs["-startY"]+1],"Start Y")))
  344. changedT.new("Start Y Position",startY) end
  345. assert(startY >= 0, errorT.zero, "StartY")
  346. if tArgs["-invCheckFreq"] then
  347. invCheckFreq = math.abs(math.floor(checkNum(tArgs[tArgs["-invCheckFreq"]+1],"Inventory Check Frequency")))
  348. changedT.new("Inventory Check Frequency",invCheckFreq) end
  349. assert(invCheckFreq ~= 0, errorT.zero, "Inventory Check Frequency")
  350. if tArgs["-keepOpen"] then
  351. keepOpen = math.abs(math.floor(checkNum(tArgs[tArgs["-keepOpen"]+1],"Open Slots")))
  352. changedT.new("Slots to keep open", keepOpen) end
  353. assert(keepOpen ~= 0 and keepOpen < 16, errorT.zero, "Open Slots")
  354. if tArgs["-ignoreResources"] then careAboutResources = false; changedT.new("Ignore Resources?", not careAboutResources) end
  355. if tArgs["-saveFile"] then saveFile = tArgs[tArgs["-saveFile"]+1] changedT.new("Save File", saveFile) end
  356. assert(#saveFile >= 2,errorT.word, "Save File")
  357. end; end --First end is for vanilla, second is for DEFAULT
  358.  
  359. local function saveProgress(extras) --Session persistence
  360. local file = fs.open(saveFile,"w")
  361. for a,b in pairs(getfenv(1)) do
  362. if type(b) == "string" then b = "\""..b.."\"" end
  363. if type(b) == "table" and a~="modem" then b = textutils.serialize(b) end
  364. if type(b) ~= "function" then
  365. file.write(a.." = "..tostring(b).."\n")
  366. end
  367. end
  368. file.write("doCheckFuel = false\n") --It has already used fuel, so calculation unnesesary
  369. if type(extras) == "table" then
  370.   for a, b in pairs(extras) do
  371.     file.write(a.." = "..tostring(b))
  372.   end
  373. end
  374. file.close()
  375. end
  376.  
  377. local area = x*z
  378. local volume = x*y*z
  379. local lastHeight = y%3
  380. local dispY = y
  381. y = math.floor(y/3)*3
  382. local yMult = y/3 + math.ceil(lastHeight/2)
  383. local moveVolumeCalc = ((area+x+z)*yMult) + (2 * dispY)
  384. local moveVolume = (area * yMult)
  385.  
  386. --Getting Fuel
  387. if doCheckFuel then --Calculating Needed Fuel
  388. local neededFuel = moveVolume + (math.floor(volume / (64 * 8)) * (x+dispY+z)) --Standard move plus dropping off supplies
  389.                              --How many times come back to start| * If it were at the very far side
  390. neededFuel = neededFuel + fuelTable[fuelSafety]
  391. if neededFuel < 100 then neededFuel = 100; end
  392. if checkFuel() < neededFuel then
  393. screen(1,1)
  394. print("More Fuel Needed")
  395. print("Current Fuel: ",checkFuel()," Needed: ",neededFuel)
  396. print("Place fuel in Bottom Right")
  397. while turtle.getItemCount(16) == 0 do
  398.   sleep(1)
  399. end
  400. turtle.select(16)
  401. while checkFuel() < neededFuel do
  402. if not turtle.refuel(1) then
  403. term.clearLine()
  404. print("Still too little fuel")
  405. term.clearLine()
  406. print("Insert more fuel to resume")
  407. while turtle.getItemCount(16) == 0 do
  408.   sleep(1)
  409. end
  410. end
  411. local x,y = term.getCursorPos()
  412. print(checkFuel().." Fuel")
  413. term.setCursorPos(x,y)
  414. end
  415. print(checkFuel().." Units of Fuel")
  416. sleep(3)
  417. turtle.select(1)
  418. end
  419. end
  420. --Initial Rednet Handshake
  421. if rednetEnabled then
  422. screen(1,1)
  423. print("Rednet is Enabled")
  424. print("The Channel to open is "..channels.send)
  425. modem = peripheral.wrap("right")
  426. modem.open(channels.receive)
  427. local i = 0
  428. repeat
  429. local id = os.startTimer(3)
  430. i=i+1
  431. print("Sending Initial Message "..i)
  432. modem.transmit(channels.send, channels.receive, "{ 'Initial' }")
  433. local message
  434. repeat
  435. local event, idCheck, channel,_,locMessage, distance = os.pullEvent()
  436. message = locMessage
  437. until (event == "timer" and idCheck == id) or (event == "modem_message" and channel == channels.receive and message == channels.confirm)
  438. until message == channels.confirm
  439. connected = true
  440. print("Connection Confirmed!")
  441. sleep(1.5)
  442. end
  443. local function biometrics(sendChannel)
  444. local commands = { Confirm = "Confirm" }
  445. local toSend = { ["x"] = x, ["y"] = (y/3 + math.ceil(lastHeight/2)), ["z"] = z, --The y calc is weird...
  446.     ["xPos"] = xPos, ["yPos"] = yPos, ["zPos"] = zPos,
  447.     ["percent"] = percent, ["mined" ]= mined,
  448.     ["fuel"] = checkFuel(), ["moved"] = moved,
  449.     ["remainingBlocks"] = (volume-mined), ["ID"] = os.getComputerID(),
  450.     ["isInPath"] = isInPath, --Whether it is going back to start
  451.     ["volume"] = volume, ["area"] = area}
  452. modem.transmit(channels.send, channels.receive, textutils.serialize(toSend))
  453. id = os.startTimer(0.1)
  454. local event, message
  455. repeat
  456. local locEvent, idCheck, confirm, _, locMessage, distance = os.pullEvent()
  457. event, message = locEvent, locMessage
  458. until (event == "timer" and idCheck == id) or (event == "modem_message" and confirm == channels.receive)
  459. if event == "modem_message" then connected = true else connected = false end
  460. --Stuff to do for different commands
  461. end
  462. --Showing changes to settings
  463. screen(1,1)
  464. print("Your selected settings:")
  465. if #changedT == 0 then
  466. print("Completely Default")
  467. else
  468. for i=1, #changedT do
  469. local title, value = changedT.getPair(i)
  470. print(capitalize(title)..": ",value)
  471. end
  472. end
  473. print("\nStarting in 3"); sleep(1); print("2"); sleep(1); print("1"); sleep(1.5)
  474.  
  475.  
  476.  
  477. ----------------------------------------------------------------
  478. --Define ALL THE FUNCTIONS
  479. function display() --This is just the last screen that displays at the end
  480. screen(1,1)
  481. print("Total Blocks Mined: "..mined)
  482. print("Current Fuel Level: "..turtle.getFuelLevel())
  483. print("Cobble: "..totals.cobble)
  484. print("Usable Fuel: "..totals.fuel)
  485. print("Other: "..totals.other)
  486. if rednetEnabled then
  487. print("")
  488. print("Sent Stop Message")
  489. finalTable = {{["Mined: "] = mined}, {["Cobble: "] = totals.cobble}, {["Fuel: "] = totals.fuel},
  490.     {["Other: "] = totals.other}, {["Fuel: "] = checkFuel()} }
  491. modem.transmit(channels.send,channels.receive,"stop")
  492. modem.transmit(channels.send,channels.receive,textutils.serialize(finalTable))
  493. modem.close(channels.receive)
  494. end
  495. if doBackup then fs.delete(saveFile) end
  496. end
  497. function updateDisplay() --Runs in Mine(), display information to the screen in a certain place
  498. screen(1,1)
  499. print("Blocks Mined")
  500. print(mined)
  501. print("Percent Complete")
  502. print(percent.."%")
  503. print("Fuel")
  504. print(checkFuel())
  505. if rednetEnabled then
  506. screenLine(1,7)
  507. print("Connected: "..tostring(connected))
  508. end
  509. end
  510. function isFull(slots)
  511.   slots = slots or 16
  512.   local numUsed = 0
  513.   sleep(0)
  514.   for i=1, slots do
  515.     if turtle.getItemCount(i) > 0 then numUsed = numUsed + 1 end
  516.   end
  517.   if numUsed >= slots then
  518.     return true
  519.   end
  520.   return false
  521. end
  522. function dig(doAdd, func)
  523.   doAdd = doAdd or true
  524.   func = func or turtle.dig
  525.   if func() then
  526.     if doAdd then
  527.       mined = mined + 1
  528.     end
  529.     return true
  530.   end
  531.   return false
  532. end
  533. function digUp(doAdd)
  534.     return dig(doAdd,turtle.digUp)
  535. end
  536. function digDown(doAdd)
  537.     return dig(doAdd,turtle.digDown)
  538. end
  539. function relativeXCalc()
  540.   if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end
  541. end
  542. function forward(doAdd)
  543.   if doAdd == nil then doAdd = true end
  544.   if turtle.forward() then
  545.     if doAdd then
  546.       moved = moved + 1
  547.     end
  548.    if facing == 0 then
  549.       xPos = xPos + 1
  550.     elseif facing == 1 then
  551.       zPos = zPos + 1
  552.     elseif facing == 2 then
  553.       xPos = xPos - 1
  554.     elseif facing == 3 then
  555.       zPos = zPos - 1
  556.     else
  557.       error("Function forward, facing should be 0 - 3, got "..tostring(facing),2)
  558.     end
  559.     relativeXCalc()
  560.     return true
  561.   end
  562.   return false
  563. end
  564. function up(sneak)
  565.   sneak = sneak or 1
  566.   if inverted and sneak == 1 then
  567.     down(-1)
  568.   else
  569.     while not turtle.up() do
  570.       if not digUp() then
  571.         attackUp()
  572.         sleep(0.5)
  573.       end
  574.     end
  575.     yPos = yPos - sneak --Oh! I feel so clever
  576.   end                   --This works because inverted :)
  577. end
  578. function down(sneak)
  579.   sneak = sneak or 1
  580.   local count = 0
  581.   if inverted and sneak == 1 then
  582.     up(-1)
  583.   else
  584.     while not turtle.down() do
  585.       count = count + 1
  586.       if not digDown() then
  587.         attackDown()
  588.         sleep(0.2)
  589.       end
  590.       if count > 20 then bedrock() end
  591.     end
  592.     yPos = yPos + sneak
  593.   end
  594. end
  595. function right(num)
  596.   num = num or 1
  597.   for i=1, num do turtle.turnRight(); facingF(1); end
  598.   saveProgress()
  599. end
  600. function left(num)
  601.   num = num or 1
  602.   for i=1, num do turtle.turnLeft(); facingF(-1) end
  603.   saveProgress()
  604. end
  605. function attack(doAdd, func)
  606.   doAdd = doAdd or true
  607.   func = func or turtle.attack
  608.   if func() then
  609.     if doAdd then
  610.       attacked = attacked + 1
  611.     end
  612.     return true
  613.   end
  614.   return false
  615. end
  616. function attackUp(doAdd)
  617.   if inverted then
  618.     return attack(doAdd, turtle.attackDown)
  619.   else
  620.     return attack(doAdd, turtle.attackUp)
  621.   end
  622. end
  623. function attackDown(doAdd)
  624.   if inverted then
  625.     return attack(doAdd, turtle.attackUp)
  626.   else
  627.     return attack(doAdd, turtle.attackDown)
  628.   end
  629. end
  630.  
  631.  
  632. function mine(doDigDown, doDigUp, outOfPath,doCheckInv) -- Basic Move Forward
  633. if doCheckInv == nil then doCheckInv = true end
  634. if doDigDown == nil then doDigDown = true end
  635. if doDigUp == nil then doDigUp = true end
  636. if outOfPath == nil then outOfPath = false end
  637. if inverted then
  638.   doDigUp, doDigDown = doDigDown, doDigUp --Just switch the two if inverted
  639. end
  640. if doRefuel and checkFuel() < 100 then
  641.   for i=1, 16 do
  642.   if turtle.getItemCount(i) > 0 then
  643.     turtle.select(i)
  644.     if checkFuel() < 200 + fuelTable[fuelSafety] then
  645.       turtle.refuel()
  646.     end
  647.   end
  648.   end
  649. end
  650. local count = 0
  651. while not forward(not outOfPath) do
  652.   sleep(0) --Calls coroutine.yield to prevent errors
  653.   count = count + 1
  654.   if not dig() then
  655.     attack()
  656.   end
  657.   if count > 10 then
  658.     attack()
  659.     sleep(0.2)
  660.   end
  661.   if count > 50 then
  662.     ran, bool = pcall(function() return turtle.getFuelLevel() > 0 end) --This is done to avoid errors. Not just "returns unlimited"
  663.     if ran and bool == true then  --When fuel is not infinite
  664.       if yPos > (startY-7) then --If it is near bedrock
  665.         bedrock()
  666.       else --Otherwise just sleep for a bit to avoid sheeps
  667.         sleep(1)
  668.       end
  669.     else
  670.       error("No Fuel/Unexpected Error",0)
  671.     end
  672.   end
  673. end
  674. if doDigUp then
  675. while turtle.detectUp() do
  676.   sleep(0) --Calls coroutine.yield
  677.   if not digUp() then
  678.     attackUp()
  679.     count = count + 1
  680.   end
  681.   if count > 50 and yPos > (startY-7) then --Same deal with bedrock as above
  682.     bedrock()
  683.   end
  684.   end
  685. end
  686. if doDigDown then
  687.  digDown()
  688. end
  689. percent = math.ceil(moved/moveVolume*100)
  690. updateDisplay()
  691. local tab = {} --This registers a change in the saveProgress file
  692. if facing == 0 then --I do this because when it restores, it always
  693.   tab.xPos = xPos + 1-- Thinks it is one position back, for some reason
  694. elseif facing == 1 then-- This overwrites that.
  695.   tab.zPos = zPos + 1
  696. elseif facing == 2 then
  697.   tab.xPos = xPos - 1
  698. elseif facing == 3 then
  699.   tab.zPos = zPos - 1
  700. end
  701. saveProgress(tab)
  702. isInPath = (not outOfPath) --For rednet
  703. if doCheckInv and careAboutResources then
  704. if moved%invCheckFreq == 0 then
  705.  if isFull(16-keepOpen) then dropOff() end
  706. end; end
  707. if rednetEnabled then biometrics() end
  708. end
  709. --Direction: Front = 0, Right = 1, Back = 2, Left = 3
  710. function facingF(num)
  711. facing = facing + num
  712. if facing > 3 then facing = 0 end
  713. if facing < 0 then facing = 3 end
  714. end
  715.  
  716. function turnTo(num, dir)
  717.   num = num or facing
  718.   dir = dir or "left"
  719.   while facing ~= num do
  720.     if dir == "left" then
  721.       left()
  722.     elseif dir == "right" then
  723.       right()
  724.     else
  725.       error("TurnTo: Left or Right expected, got "..tosrting(dir))
  726.       end
  727.   end
  728. end
  729. function goto(x,z,y, toFace)
  730. --Will first go to desired z pos, then x pos, y pos varies
  731. x = x or 1; y = y or 1; z = z or 1; toFace = toFace or facing
  732. gotoX,gotoY,gotoZ,gotoFacing = xPos,yPos,zPos,facing --For use in session persistence
  733. if yPos > y then --Will go up first if below position
  734.   while yPos~=y do up() end
  735. end
  736. if zPos > z then
  737.   turnTo(3)
  738. elseif zPos < z then
  739.   turnTo(1)
  740. end
  741. while zPos ~= z do mine(false,false,true,false) end
  742. if xPos > x then
  743.   turnTo(2)
  744. elseif xPos < x then
  745.   turnTo(0)
  746. end
  747. while xPos ~= x do mine(false,false,true,false) end
  748. if yPos < y then --Will go down after if above position
  749.   while yPos~=y do down() end
  750. end
  751. turnTo(toFace,"right")
  752. saveProgress()
  753. gotoX,gotoY,gotoZ,gotoFacing = nil
  754. end
  755. function drop(side, final, allowSkip)
  756. side = sides[side] or "front"    --The final number means that it will
  757. if final then final = 0 else final = 1 end --drop a whole stack at the end
  758. local allowSkip = allowSkip or (final == 0) --This will allow drop(side,t/f, rednetConnected)
  759. count()
  760. if doRefuel then
  761.   for i=1, 16 do
  762.     if slot[i][1] == 2 then
  763.       turtle.select(i); turtle.refuel()
  764.     end
  765.   end
  766.   turtle.select(1)
  767. end
  768. if side == "right" then turnTo(1) end
  769. if side == "left" then turnTo(3) end
  770. local whereDetect, whereDrop1, whereDropAll
  771. local _1 = slot[1][2] - final --All but one if final, all if not final
  772. if side == "top" then
  773. whereDetect = turtle.detectUp ; whereDrop = turtle.dropUp
  774. elseif side == "bottom" then
  775. whereDetect = turtle.detectDown ; whereDrop = turtle.dropDown
  776. else
  777. whereDetect = turtle.detect; whereDrop = turtle.drop
  778. end
  779. local function waitDrop(val) --This will just drop, but wait if it can't
  780.   val = val or 64
  781.   local try = 1
  782.   while not whereDrop(val) do
  783.     print("Chest Full, Try "..try)
  784.     try = try + 1
  785.     sleep(2)
  786.   end
  787. end
  788. repeat
  789. local detected = whereDetect()
  790. if detected then
  791.   waitDrop(_1)
  792.   for i=2, 16 do
  793.     if turtle.getItemCount(i) > 0 then
  794.       turtle.select(i)
  795.       waitDrop()
  796.     end
  797.   end
  798. elseif not allowSkip then
  799.   print("Waiting for chest placement place a chest to continue")
  800.   while not whereDetect() do
  801.     sleep(1)
  802.   end
  803. end
  804. until detected or allowSkip
  805. if not allowSkip then totals.cobble = totals.cobble - 1 end
  806. turtle.select(1)
  807. turnTo(0)
  808. end
  809. function dropOff() --Not local because called in mine()
  810. local currX,currZ,currY,currFacing = xPos, zPos, yPos, facing
  811. goto(0,1,1,2)
  812. drop(dropSide,false)
  813. mine(false,false,true, false)
  814. goto(1,1,1, 0)
  815. goto(currX,currZ,currY,currFacing)
  816. end
  817. function bedrock()
  818. local origin = {x = xPos, y = yPos, z = zPos}
  819. print("Bedrock Detected")
  820. if turtle.detectUp() then
  821. print("Block Above")
  822. local var
  823. if facing == 0 then var = 2 elseif facing == 2 then var = 0 else error("Was facing left or right on bedrock") end
  824. goto(xPos,zPos,yPos,var)
  825. for i=1, relxPos do mine(true,true); end
  826. end
  827. goto(0,1,1,2)
  828. drop(dropSide, true)
  829. display()
  830. print("\nFound bedrock at these coordinates: ")
  831. print(origin.x," Was position in row\n",origin.z," Was row in layer\n",origin.y," Blocks down from start")
  832. error("",0)
  833. end
  834. -------------------------------------------------------------------------------------
  835. --Pre-Mining Stuff dealing with session persistence
  836. local doDigDown, doDigUp = (lastHeight ~= 1), false --Used in lastHeight
  837. if not restoreFound then mine(false,false, true) else digUp(); digDown() end --Get it into the quarry
  838. if gpsEnabled and not restoreFound then --The initial locate is done in the arguments. This is so I can figure out what quadrant the turtle is in.
  839.   gpsSecondPos = {gps.locate(gpsTimeout)} --Note: Does not run this if it has already been restarted.
  840. end
  841. if restoreFound then
  842.   if gotoX then
  843.     goto(gotoX,gotoZ,gotoY,gotoFacing)
  844.   end
  845.   local func
  846.   if rowCheck == "left" then func = right else func = left end
  847.   if endRow == 1 then
  848.     mine()
  849.     func()
  850.   elseif endRow == 2 then
  851.     func()
  852.   end
  853. end
  854. if y ~= 0 and not restoreFound then down() end
  855. --Mining Loops
  856. turtle.select(1)
  857. while layersDone <= y do -------------Height---------
  858. moved = moved + 1 --To account for the first position in row as "moved"
  859. if not restoreFound then rowCheck = "right" end
  860. relativeXCalc()
  861. while zPos <= z do -------------Width----------
  862. while relxPos < x do ------------Length---------
  863. mine()
  864. end ---------------Length End-------
  865. if zPos ~= z then
  866. local func
  867. if rowCheck == "right" and zPos ~= z then --Swithcing to next row
  868.   func = right; rowCheck = "left"; else func = left; rowCheck = "right" end --Which way to turn
  869.   func()
  870.   endRow = 1
  871.   mine()
  872.   endRow = 2
  873.   func()
  874.   endRow = 0
  875. else break
  876. end
  877. end ---------------Width End--------
  878. goto(1,1,yPos,0)
  879. if yPos+1 ~= y then
  880.   for i=1, 3 do down() end
  881. end
  882. layersDone = layersDone + 3
  883. restoreFound = false --This is done so that rowCheck works properly upon restore
  884. end ---------------Height End-------
  885. if lastHeight ~= 0 then ---------LAST ROW--------- (copied from above)
  886. moved = moved + 1 --To account for the first position in row as "moved"
  887. if y ~= 0 then --If the basic y == 2 or 1
  888.   for i=1, 2 do down() end
  889. end
  890. if not restoreFound then rowCheck = "right" end
  891. relativeXCalc()
  892. while zPos <= z do -------------Width----------
  893. while relxPos < x do ------------Length---------
  894. mine(doDigDown,doDigUp)
  895. end ---------------Length End-------
  896. if zPos ~= z then
  897. local func
  898. if rowCheck == "right" and zPos ~= z then --Swithcing to next row
  899.   func = right; rowCheck = "left"; else func = left; rowCheck = "right" end --Which way to turn
  900.   func()
  901.   endRow = 1
  902.   mine(doDigDown,doDigUp)
  903.   endRow = 2
  904.   func()
  905.   endRow = 0
  906. else break
  907. end
  908. end ---------------Width End--------
  909. goto(1,1,yPos,0)
  910. end
  911. if doDigDown then
  912.   if inverted then
  913.     digUp()
  914.   else
  915.     digDown()
  916.   end
  917. end
  918. goto(0,1,1,2)
  919.  
  920. --Output to a chest or sit there
  921. drop(dropSide, true)
  922. --Display was moved above to be used in bedrock function
  923. display()
Add Comment
Please, Sign In to add comment