Guest User

Quarry 3.2.2

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