Guest User

Quarry 3.2.1

a guest
Sep 21st, 2013
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2. Version 3.2.1
  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, endRow, startY
  145. = 0, 1, 1, 0, 0, 0, 0, 1, "right", false, true, 1, 0, 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.  
  172. do --Common variable name...
  173. local flag = turtle.getFuelLevel() ~= "Unlimited"
  174. turtle.getFuelLevel = function() --Unlimited screws up my calculations
  175. if not flag then --Also, this may or may not screw it up for other programs that run...
  176. return getFuel()
  177. else
  178. return math.huge --Lol... Should work for my purposes
  179. end
  180. end
  181. end
  182. local checkFuel = turtle.getFuelLevel --Just an alias for backwards compat
  183. local getFuel = turtle.getFuelLevel
  184.  
  185. -----------------------------------------------------------------
  186. --Input Phase
  187. local function screen(xPos,yPos)
  188. xPos, yPos = xPos or 1, yPos or 1
  189. term.setCursorPos(xPos,yPos); term.clear(); end
  190. local function screenLine(xPos,yPos)
  191. term.setCursorPos(xPos,yPos); term.clearLine(); end
  192.  
  193. screen(1,1)
  194. print("----- Welcome to Quarry! -----")
  195. print("")
  196.  
  197. local sides = {top = "top", right = "right", left = "left", bottom = "bottom", front = "front"} --Used to whitelist sides
  198. local errorT = {num = "Numbers not recognized", zero = "Variable is out of range", word = "String failed assertion" }
  199. local changedT = {}
  200. changedT.new = function(key, value) changedT[#changedT+1] = {[key] = value} end
  201. changedT.getPair = function(i) for a, b in pairs(changedT[i]) do return a, b end end
  202. local function capitalize(text) return (string.upper(string.sub(text,1,1))..string.sub(text,2,-1)) end
  203. 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
  204. local function checkNum(number, section) return assert(tonumber(number),errorT.num, section) end
  205. tArgs.checkStart = function(num) tArgs[tArgs[num]] = num end
  206. for i=1, #tArgs do tArgs.checkStart(i) end
  207.  
  208. --Check if it is a turtle
  209. if not turtle then
  210. print("This is not a turtle, you must be looking for the \"Companion Rednet Program\" \nCheck My forum thread for that")
  211. print("Press 'q' to quit, or any other key to start help ")
  212. if ({os.pullEvent("char")})[2] ~= "q" then tArgs.help = true else error("",0) end
  213. end
  214.  
  215.  
  216. if tArgs["help"] or tArgs["-help"] or tArgs["-?"] or tArgs["?"] then
  217. print("You have selected help, press any key to continue"); print("Use arrow keys to naviate, q to quit"); os.pullEvent("key")
  218. local pos = 1
  219. local key = 0
  220. while pos <= #help and key ~= keys.q do
  221. if pos < 1 then pos = 1 end
  222. screen(1,1)
  223. print(help[pos].title)
  224. for a=1, #help[pos] do print(help[pos][a]) end
  225. repeat
  226. _, key = os.pullEvent("key")
  227. until key == 200 or key == 208 or key == keys.q
  228. if key == 200 then pos = pos - 1 end
  229. if key == 208 then pos = pos + 1 end
  230. end
  231. error("",0)
  232. end
  233.  
  234. --Saving
  235. if tArgs["doBackup"] then doBackup = (string.lower(string.sub(tArgs[tArgs["doBackup"]+1],1,1)) ~= "f") end
  236. if tArgs["saveFile"] then saveFile = tArgs[tArgs["saveFile"]+1] or saveFile end
  237.  
  238. local restoreFound = false
  239. if tArgs["-restore"] or tArgs["-resume"] then
  240. restoreFound = fs.exists(saveFile)
  241. if restoreFound then
  242. os.run(getfenv(1),saveFile)
  243. if gpsEnabled then --If it had saved gps coordinates
  244. print("Found GPS Start Coordinates")
  245. local currLoc = {gps.locate(gpsTimeout)}
  246. if #currLoc > 0 and #gpsStartPos > 0 and #gpsSecondPos > 0 then --Cover all the different positions I'm using
  247. print("GPS Position Successfully Read")
  248. if currLoc[1] == gpsStartPos[1] and currLoc[3] == gpsStartPos[3] then --X coord, y coord, z coord in that order
  249. xPos, yPos, zPos = 0,1,1
  250. if facing ~= 0 then turnTo(0) end
  251. print("Is at start")
  252. else
  253. if inverted then --yPos setting
  254. ------------------------------------------------FIX THIS
  255. end
  256. local function copyTable(tab) local toRet = {}; for a, b in pairs(tab) do toRet[a] = b end; return toRet end
  257. local a, b = copyTable(gpsStartPos), copyTable(gpsSecondPos) --For convenience
  258. if b[3] - a[3] == -1 then--If went north (-Z)
  259. a[1] = a[1] - 1 --Shift x one to west to create a "zero"
  260. xPos, zPos = -currLoc[3] + a[3], currLoc[1] + -a[1]
  261. elseif b[1] - a[1] == 1 then--If went east (+X)
  262. a[3] = a[3] - 1 --Shift z up one to north to create a "zero"
  263. xPos, zPos = currLoc[1] + -a[1], currLoc[3] + -a[3]
  264. elseif b[3] - a[3] == 1 then--If went south (+Z)
  265. a[1] = a[1] + 1 --Shift x one to east to create a "zero"
  266. xPos, zPos = currLoc[3] + a[3], -currLoc[1] + a[3]
  267. elseif b[1] - a[1] == -1 then--If went west (-X)
  268. a[3] = a[3] + 1 --Shift z down one to south to create a "zero"
  269. xPos, zPos = -currLoc[1] + a[1], -currLoc[3] + a[3]
  270. else
  271. print("Improper Coordinates")
  272. print("GPS Locate Failed, Using Standard Methods") ----Maybe clean this up a bit to use flags instead.
  273. end
  274. end
  275. print("X Pos: ",xPos)
  276. print("Y Pos: ",yPos)
  277. print("Z Pos: ",zPos)
  278. print("Facing: ",facing)
  279. else
  280. print("GPS Locate Failed, Using Standard Methods")
  281. end
  282. print("Restore File read successfully. Starting in 3"); sleep(3)
  283. end
  284. end
  285. else
  286. originalFuel = checkFuel() --For use in logging. To see how much fuel is REALLY used
  287. end
  288.  
  289. if not (tArgs["-DEFAULT"] or restoreFound) then
  290. --Just a note, the whole error checking section here was more of an
  291. --experiment than anything else. If its ever changed in the future,
  292. --it would probably be for the better.
  293. local section = "Dimensions"
  294. --Dimesnions
  295. if tArgs["-dim"] then local num = tArgs["-dim"];
  296. x = checkNum(tArgs[num + 1],section); z = checkNum(tArgs[num + 2],section); y = checkNum(tArgs[num + 3],section)
  297. else
  298. print("What dimensions?")
  299. print("")
  300. --This will protect from negatives, letters, and decimals
  301. term.write("Length: ")
  302. x = math.floor(math.abs(tonumber(io.read()) or x))
  303. term.write("Width: ")
  304. z = math.floor(math.abs(tonumber(io.read()) or z))
  305. term.write("Height: ")
  306. y = math.floor(math.abs(tonumber(io.read()) or y))
  307. end
  308. changedT.new("x",x); changedT.new("z",z); changedT.new("y",y)
  309. assert(x~=0, errorT.zero, section); assert(z~=0, errorT.zero, section); assert(y~=0, errorT.zero, section)
  310. assert(not(x == 1 and y == 1 and z == 1) ,"1, 1, 1 dosen't work well at all, try again", section)
  311. if not tArgs["-vanilla"] then
  312. --Invert
  313. if tArgs["-invert"] then
  314. inverted = (string.lower(string.sub(tArgs[tArgs["-invert"]+1] or "",1,1)) == "t") else
  315. term.write("Inverted? ")
  316. inverted = (string.lower(string.sub(io.read(),1,1)) == "y")
  317. end
  318. changedT.new("Inverted", inverted)
  319. --Rednet
  320. if supportsRednet then
  321. if tArgs["-rednet"] then
  322. rednetEnabled = (string.lower(string.sub(tArgs[tArgs["-rednet"]+1] or "",1,1)) == "t")
  323. else term.write("Rednet? "); rednetEnabled = (string.lower(string.sub(io.read(),1,1)) == "y")
  324. if (tArgs["-GPS"] or tArgs["-gps"]) and not restoreFound and not gpsEnabled then --The not gps enabled makes it so it is toggled
  325. gpsStartPos = {gps.locate(gpsTimeout)} --Stores position in array
  326. gpsEnabled = #gpsStartPos > 0 --Checks if location received properly
  327. changedT.new("GPS Location Services", gpsEnabled)
  328. end
  329. changedT.new("Rednet Enabled", rednetEnabled)
  330. end
  331. if tArgs["-sendChannel"] then
  332. channels.send = assert(tonumber(tArgs[tArgs["-sendChannel"]+1]), errorT.num)
  333. assert(channels.send > 0 and channels.send < 65535, errorT.zero)
  334. changedT.new("Send Channel",channels.send) end
  335. if tArgs["-receiveChannel"] then
  336. channels.receive = assert(tonumber(tArgs[tArgs["-receiveChannel"]+1]), errorT.num)
  337. assert(channels.receive > 0 and channels.receive < 65535 and channels.receive ~= channels.send, errorT.zero)
  338. changedT.new("Receive Channel",channels.receive) end
  339. end
  340. --Fuel
  341. if tArgs["-doRefuel"] then doRefuel = not doRefuel; changedT.new("Do Refuel",doRefuel) end
  342. if turtle.getFuelLevel() == "unlimited" then
  343. doCheckFuel = false
  344. else
  345. if tArgs["-doCheckFuel"] then
  346. doCheckFuel = (string.lower(string.sub(tArgs[tArgs["-doCheckFuel"]+1] or "",1,1)) == "t"); changedT.new("Do Check Fuel", doCheckFuel) end
  347. end
  348. if tArgs["-chest"] then
  349. dropSide = sides[tArgs[tArgs["-chest"]+1]] or dropSide; changedT.new("Chest Side",dropSide) end
  350. if tArgs["-fuelSafety"] then local loc = tArgs[tArgs["-fuelSafety"]+1]
  351. if fuelTable[loc] then
  352. fuelSafety = loc; changedT.new("Fuel Check Safety", fuelSafety)
  353. end
  354. end
  355. --Logging
  356. logging = (tArgs["-log"] and true) or logging --The and will set it to true if value, or its original value if nil
  357. if logging then changedT.new("Logging",logging) end
  358. if tArgs["-logFolder"] then logFolder = tArgs[tArgs["-logFolder"]+1] or logFolder; changedT.new("Log Folder",logFolder) end
  359. if tArgs["-logExtension"] then logExtension = tArgs[tArgs["-logExtension"]+1] or logExtension; changedT.new("Log Extension",logExtension) end
  360. --Misc
  361. if tArgs["-startY"] then
  362. startY = math.abs(math.floor(checkNum(tArgs[tArgs["-startY"]+1],"Start Y")))
  363. changedT.new("Start Y Position",startY) end
  364. assert(startY >= 0, errorT.zero, "StartY")
  365. if tArgs["-invCheckFreq"] then
  366. invCheckFreq = math.abs(math.floor(checkNum(tArgs[tArgs["-invCheckFreq"]+1],"Inventory Check Frequency")))
  367. changedT.new("Inventory Check Frequency",invCheckFreq) end
  368. assert(invCheckFreq ~= 0, errorT.zero, "Inventory Check Frequency")
  369. if tArgs["-keepOpen"] then
  370. keepOpen = math.abs(math.floor(checkNum(tArgs[tArgs["-keepOpen"]+1],"Open Slots")))
  371. changedT.new("Slots to keep open", keepOpen) end
  372. assert(keepOpen ~= 0 and keepOpen < 16, errorT.zero, "Open Slots")
  373. if tArgs["-ignoreResources"] then careAboutResources = false; changedT.new("Ignore Resources?", not careAboutResources) end
  374. if tArgs["-saveFile"] then saveFile = tArgs[tArgs["-saveFile"]+1] changedT.new("Save File", saveFile) end
  375. assert(#saveFile >= 2,errorT.word, "Save File")
  376. end; end --First end is for vanilla, second is for DEFAULT
  377.  
  378. local function saveProgress(extras) --Session persistence
  379. if doBackup then
  380. local file = fs.open(saveFile,"w")
  381. for a,b in pairs(getfenv(1)) do
  382. if type(b) == "string" then b = "\""..b.."\"" end
  383. if type(b) == "table" and a~="modem" then b = textutils.serialize(b) end
  384. if type(b) ~= "function" then
  385. file.write(a.." = "..tostring(b).."\n")
  386. end
  387. end
  388. file.write("doCheckFuel = false\n") --It has already used fuel, so calculation unnesesary
  389. if type(extras) == "table" then
  390. for a, b in pairs(extras) do
  391. file.write(a.." = "..tostring(b))
  392. end
  393. end
  394. file.close()
  395. end
  396. end
  397.  
  398. local area = x*z
  399. local volume = x*y*z
  400. local lastHeight = y%3
  401. local dispY = y
  402. y = math.floor(y/3)*3
  403. local yMult = y/3 + math.ceil(lastHeight/2) --This is basically a smart y/3 for movement
  404. local moveVolume = (area * yMult) --Kept for display percent
  405. --Calculating Needed Fuel--
  406. local exStack = numberOfStacksPerRun --Expected stacks of items before full
  407. neededFuel = yMult * x * z + --This is volume it will run through
  408. 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
  409. (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
  410. --Original equation: x*z*y/3 + y * 2 + (x+z) * y/3 + (x + z + y) * (1/64*8)
  411. neededFuel = math.ceil(neededFuel)
  412.  
  413. --Getting Fuel
  414. if doCheckFuel and checkFuel() < neededFuel then
  415. neededFuel = neededFuel + fuelTable[fuelSafety] --For safety
  416. print("Not enough fuel")
  417. print("Current: ",checkFuel()," Needed: ",neededFuel)
  418. print("Starting SmartFuel")
  419. sleep(1) --So they can read everything.
  420. term.clear()
  421. local oneFuel, neededFuelItems
  422. local currSlot = 0
  423. local function output(text, x, y) --For displaying fuel
  424. currX, currY = term.getCursorPos()
  425. term.setCursorPos(x,y)
  426. term.clearLine()
  427. term.write(text)
  428. term.setCursorPos(currX,currY)
  429. end
  430. local function roundTo(num, target) --For stacks of fuel
  431. if num >= target then return target else return num end
  432. end
  433. local function updateScreen()
  434. output("Welcome to SmartFuel! Now Refueling...", 1,1)
  435. output("Currently taking fuel from slot "..currSlot,1,2)
  436. output("Current single fuel: "..tostring(oneFuel or 0),1,3)
  437. output("Current estimate of needed fuel: ",1,4)
  438. output("Single Items: "..math.floor(neededFuelItems or 0),4,5)
  439. output("Stacks: "..math.ceil((neededFuelItems or 0) / 64),4,6)
  440. output("Needed Fuel: "..tostring(neededFuel),1,12)
  441. output("Current Fuel: "..tostring(checkFuel()),1,13)
  442. end
  443. while checkFuel() <= neededFuel do
  444. currSlot = currSlot + 1
  445. turtle.select(currSlot)
  446. updateScreen()
  447. while turtle.getItemCount(currSlot) == 0 do sleep(1.5) end
  448. repeat
  449. local previous = checkFuel()
  450. turtle.refuel(1)
  451. oneFuel = checkFuel() - previous
  452. updateScreen()
  453. until (oneFuel or 0) > 0 --Not an if to prevent errors if fuel taken out prematurely.
  454. neededFuelItems = (neededFuel - checkFuel()) / oneFuel
  455. turtle.refuel(roundTo(neededFuelItems, 64)) --Change because can only think about 64 at once.
  456. if turtle.getItemCount(roundTo(currSlot + 1, 16)) == 0 then --Resets if no more fuel
  457. currSlot = 0
  458. end
  459. end
  460. -- local neededFuel = moveVolume + (math.floor(volume / (64 * 8)) * (x+dispY+z)) --Standard move plus dropping off supplies
  461. -- --How many times come back to start| * If it were at the very far side
  462. -- neededFuel = neededFuel + fuelTable[fuelSafety]
  463. -- if neededFuel < 100 then neededFuel = 100; end
  464. -- if checkFuel() < neededFuel then
  465. -- screen(1,1)
  466. -- print("More Fuel Needed")
  467. -- print("Current Fuel: ",checkFuel()," Needed: ",neededFuel)
  468. -- print("Place fuel in Bottom Right")
  469. -- while turtle.getItemCount(16) == 0 do
  470. -- sleep(1)
  471. -- end
  472. -- turtle.select(16)
  473. -- while checkFuel() < neededFuel do
  474. -- if not turtle.refuel(1) then
  475. -- term.clearLine()
  476. -- print("Still too little fuel")
  477. -- term.clearLine()
  478. -- print("Insert more fuel to resume")
  479. -- while turtle.getItemCount(16) == 0 do
  480. -- sleep(1)
  481. -- end
  482. -- end
  483. -- local x,y = term.getCursorPos()
  484. -- print(checkFuel().." Fuel")
  485. -- term.setCursorPos(x,y)
  486. -- end
  487. -- print(checkFuel().." Units of Fuel")
  488. -- sleep(3)
  489. -- turtle.select(1)
  490. -- end
  491. end
  492. --Initial Rednet Handshake
  493. if rednetEnabled then
  494. screen(1,1)
  495. print("Rednet is Enabled")
  496. print("The Channel to open is "..channels.send)
  497. modem = peripheral.wrap("right")
  498. modem.open(channels.receive)
  499. local i = 0
  500. repeat
  501. local id = os.startTimer(3)
  502. i=i+1
  503. print("Sending Initial Message "..i)
  504. modem.transmit(channels.send, channels.receive, "{ 'Initial' }")
  505. local message
  506. repeat
  507. local event, idCheck, channel,_,locMessage, distance = os.pullEvent()
  508. message = locMessage
  509. until (event == "timer" and idCheck == id) or (event == "modem_message" and channel == channels.receive and message == channels.confirm)
  510. until message == channels.confirm
  511. connected = true
  512. print("Connection Confirmed!")
  513. sleep(1.5)
  514. end
  515. local function biometrics(sendChannel)
  516. local commands = { Confirm = "Confirm" }
  517. local toSend = { ["x"] = x, ["y"] = (y/3 + math.ceil(lastHeight/2)), ["z"] = z, --The y calc is weird...
  518. ["xPos"] = xPos, ["yPos"] = yPos, ["zPos"] = zPos,
  519. ["percent"] = percent, ["mined" ]= mined,
  520. ["fuel"] = checkFuel(), ["moved"] = moved,
  521. ["remainingBlocks"] = (volume-mined), ["ID"] = os.getComputerID(),
  522. ["isInPath"] = isInPath, --Whether it is going back to start
  523. ["volume"] = volume, ["area"] = area}
  524. modem.transmit(channels.send, channels.receive, textutils.serialize(toSend))
  525. id = os.startTimer(0.1)
  526. local event, message
  527. repeat
  528. local locEvent, idCheck, confirm, _, locMessage, distance = os.pullEvent()
  529. event, message = locEvent, locMessage
  530. until (event == "timer" and idCheck == id) or (event == "modem_message" and confirm == channels.receive)
  531. if event == "modem_message" then connected = true else connected = false end
  532. --Stuff to do for different commands
  533. end
  534. --Showing changes to settings
  535. screen(1,1)
  536. print("Your selected settings:")
  537. if #changedT == 0 then
  538. print("Completely Default")
  539. else
  540. for i=1, #changedT do
  541. local title, value = changedT.getPair(i)
  542. print(capitalize(title)..": ",value)
  543. end
  544. end
  545. print("\nStarting in 3"); sleep(1); print("2"); sleep(1); print("1"); sleep(1.5) --Dramatic pause at end
  546.  
  547.  
  548.  
  549. ----------------------------------------------------------------
  550. --Define ALL THE FUNCTIONS
  551. function display() --This is just the last screen that displays at the end
  552. screen(1,1)
  553. print("Total Blocks Mined: "..mined)
  554. print("Current Fuel Level: "..turtle.getFuelLevel())
  555. print("Cobble: "..totals.cobble)
  556. print("Usable Fuel: "..totals.fuel)
  557. print("Other: "..totals.other)
  558. if rednetEnabled then
  559. print("")
  560. print("Sent Stop Message")
  561. finalTable = {{["Mined: "] = mined}, {["Cobble: "] = totals.cobble}, {["Fuel: "] = totals.fuel},
  562. {["Other: "] = totals.other}, {["Fuel: "] = checkFuel()} }
  563. modem.transmit(channels.send,channels.receive,"stop")
  564. modem.transmit(channels.send,channels.receive,textutils.serialize(finalTable))
  565. modem.close(channels.receive)
  566. end
  567. if doBackup then fs.delete(saveFile) end
  568. end
  569. function updateDisplay() --Runs in Mine(), display information to the screen in a certain place
  570. screen(1,1)
  571. print("Blocks Mined")
  572. print(mined)
  573. print("Percent Complete")
  574. print(percent.."%")
  575. print("Fuel")
  576. print(checkFuel())
  577. if rednetEnabled then
  578. screenLine(1,7)
  579. print("Connected: "..tostring(connected))
  580. end
  581. end
  582. function logMiningRun(textExtension, extras) --Logging mining runs
  583. if logging then
  584. local number
  585. if not fs.isDir(logFolder) then
  586. fs.delete(logFolder)
  587. fs.makeDir(logFolder)
  588. number = 1
  589. else
  590. local i = 0
  591. repeat
  592. i = i + 1
  593. until not fs.exists(logFolder.."/Quarry_Log_"..tostring(i)..(textExtension or ""))
  594. number = i
  595. end
  596. handle = fs.open(logFolder.."/Quarry_Log_"..tostring(number)..(textExtension or ""),"w")
  597. local function write(...)
  598. for a, b in ipairs({...}) do
  599. handle.write(tostring(b))
  600. end
  601. handle.write("\n")
  602. end
  603. write("Welcome to the Quarry Logs!")
  604. write("Entry Number: ",number)
  605. write("Dimensions (X Z Y): ",x," ",z," ", dispY)
  606. write("Blocks Mined: ", mined)
  607. write(" Cobble: ", totals.cobble)
  608. write(" Usable Fuel: ", totals.fuel)
  609. write(" Other: ",totals.other)
  610. write("Total Fuel Used: ", originalFuel- checkFuel())
  611. write("Expected Fuel Use: ", neededFuel)
  612. handle.close()
  613. end
  614. end
  615. function isFull(slots)
  616. slots = slots or 16
  617. local numUsed = 0
  618. sleep(0)
  619. for i=1, slots do
  620. if turtle.getItemCount(i) > 0 then numUsed = numUsed + 1 end
  621. end
  622. if numUsed >= slots then
  623. return true
  624. end
  625. return false
  626. end
  627. function dig(doAdd, func)
  628. doAdd = doAdd or true
  629. func = func or turtle.dig
  630. if func() then
  631. if doAdd then
  632. mined = mined + 1
  633. end
  634. return true
  635. end
  636. return false
  637. end
  638. function digUp(doAdd)
  639. return dig(doAdd,turtle.digUp)
  640. end
  641. function digDown(doAdd)
  642. return dig(doAdd,turtle.digDown)
  643. end
  644. function relativeXCalc()
  645. if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end
  646. end
  647. function forward(doAdd)
  648. if doAdd == nil then doAdd = true end
  649. if turtle.forward() then
  650. if doAdd then
  651. moved = moved + 1
  652. end
  653. if facing == 0 then
  654. xPos = xPos + 1
  655. elseif facing == 1 then
  656. zPos = zPos + 1
  657. elseif facing == 2 then
  658. xPos = xPos - 1
  659. elseif facing == 3 then
  660. zPos = zPos - 1
  661. else
  662. error("Function forward, facing should be 0 - 3, got "..tostring(facing),2)
  663. end
  664. relativeXCalc()
  665. return true
  666. end
  667. return false
  668. end
  669. function up(sneak)
  670. sneak = sneak or 1
  671. if inverted and sneak == 1 then
  672. down(-1)
  673. else
  674. while not turtle.up() do
  675. if not digUp() then
  676. attackUp()
  677. sleep(0.5)
  678. end
  679. end
  680. yPos = yPos - sneak --Oh! I feel so clever
  681. end --This works because inverted :)
  682. end
  683. function down(sneak)
  684. sneak = sneak or 1
  685. local count = 0
  686. if inverted and sneak == 1 then
  687. up(-1)
  688. else
  689. while not turtle.down() do
  690. count = count + 1
  691. if not digDown() then
  692. attackDown()
  693. sleep(0.2)
  694. end
  695. if count > 20 then bedrock() end
  696. end
  697. yPos = yPos + sneak
  698. end
  699. end
  700. function right(num)
  701. num = num or 1
  702. for i=1, num do facingF(1); saveProgress(); turtle.turnRight() end
  703. end
  704. function left(num)
  705. num = num or 1
  706. for i=1, num do facingF(-1); saveProgress(); turtle.turnLeft() end
  707. end
  708. function attack(doAdd, func)
  709. doAdd = doAdd or true
  710. func = func or turtle.attack
  711. if func() then
  712. if doAdd then
  713. attacked = attacked + 1
  714. end
  715. return true
  716. end
  717. return false
  718. end
  719. function attackUp(doAdd)
  720. if inverted then
  721. return attack(doAdd, turtle.attackDown)
  722. else
  723. return attack(doAdd, turtle.attackUp)
  724. end
  725. end
  726. function attackDown(doAdd)
  727. if inverted then
  728. return attack(doAdd, turtle.attackUp)
  729. else
  730. return attack(doAdd, turtle.attackDown)
  731. end
  732. end
  733.  
  734.  
  735. function mine(doDigDown, doDigUp, outOfPath,doCheckInv) -- Basic Move Forward
  736. if doCheckInv == nil then doCheckInv = true end
  737. if doDigDown == nil then doDigDown = true end
  738. if doDigUp == nil then doDigUp = true end
  739. if outOfPath == nil then outOfPath = false end
  740. if inverted then
  741. doDigUp, doDigDown = doDigDown, doDigUp --Just switch the two if inverted
  742. end
  743. if doRefuel and checkFuel() <= fuelTable[fuelSafety]/2 then
  744. for i=1, 16 do
  745. if turtle.getItemCount(i) > 0 then
  746. turtle.select(i)
  747. if checkFuel() < 200 + fuelTable[fuelSafety] then
  748. turtle.refuel()
  749. end
  750. end
  751. end
  752. end
  753. local count = 0
  754. while not forward(not outOfPath) do
  755. sleep(0) --Calls coroutine.yield to prevent errors
  756. count = count + 1
  757. if not dig() then
  758. attack()
  759. end
  760. if count > 10 then
  761. attack()
  762. sleep(0.2)
  763. end
  764. if count > 50 then
  765. if turtle.getFuelLevel() == 0 then --Don't worry about inf fuel because I modified this function
  766. saveProgress()
  767. error("No more fuel",0)
  768. elseif yPos > (startY-7) then --If it is near bedrock
  769. bedrock()
  770. else --Otherwise just sleep for a bit to avoid sheeps
  771. sleep(1)
  772. end
  773. end
  774. end
  775. local tab = {} --This registers a change in the saveProgress file
  776. if facing == 0 then --I do this because when it restores, it always
  777. tab.xPos = xPos + 1-- Thinks it is one position back, for some reason
  778. elseif facing == 1 then-- This overwrites that.
  779. tab.zPos = zPos + 1
  780. elseif facing == 2 then
  781. tab.xPos = xPos - 1
  782. elseif facing == 3 then
  783. tab.zPos = zPos - 1
  784. end
  785. saveProgress(tab)
  786. if doDigUp then
  787. while turtle.detectUp() do
  788. sleep(0) --Calls coroutine.yield
  789. if not digUp() then
  790. attackUp()
  791. count = count + 1
  792. end
  793. if count > 50 and yPos > (startY-7) then --Same deal with bedrock as above
  794. bedrock()
  795. end
  796. end
  797. end
  798. if doDigDown then
  799. digDown()
  800. end
  801. percent = math.ceil(moved/moveVolume*100)
  802. updateDisplay()
  803. isInPath = (not outOfPath) --For rednet
  804. if doCheckInv and careAboutResources then
  805. if moved%invCheckFreq == 0 then
  806. if isFull(16-keepOpen) then dropOff() end
  807. end; end
  808. if rednetEnabled then biometrics() end
  809. end
  810. --Direction: Front = 0, Right = 1, Back = 2, Left = 3
  811. function facingF(num)
  812. facing = facing + num
  813. if facing > 3 then facing = 0 end
  814. if facing < 0 then facing = 3 end
  815. end
  816.  
  817. function turnTo(num, dir)
  818. num = num or facing
  819. dir = dir or "left"
  820. while facing ~= num do
  821. if dir == "left" then
  822. left()
  823. elseif dir == "right" then
  824. right()
  825. else
  826. error("TurnTo: Left or Right expected, got "..tosrting(dir))
  827. end
  828. end
  829. end
  830. function goto(x,z,y, toFace)
  831. --Will first go to desired z pos, then x pos, y pos varies
  832. x = x or 1; y = y or 1; z = z or 1; toFace = toFace or facing
  833. gotoX,gotoY,gotoZ,gotoFacing = xPos,yPos,zPos,facing --For use in session persistence
  834. if yPos > y then --Will go up first if below position
  835. while yPos~=y do up() end
  836. end
  837. if zPos > z then
  838. turnTo(3)
  839. elseif zPos < z then
  840. turnTo(1)
  841. end
  842. while zPos ~= z do mine(false,false,true,false) end
  843. if xPos > x then
  844. turnTo(2)
  845. elseif xPos < x then
  846. turnTo(0)
  847. end
  848. while xPos ~= x do mine(false,false,true,false) end
  849. if yPos < y then --Will go down after if above position
  850. while yPos~=y do down() end
  851. end
  852. turnTo(toFace,"right")
  853. saveProgress()
  854. gotoX,gotoY,gotoZ,gotoFacing = nil
  855. end
  856. function drop(side, final, allowSkip)
  857. side = sides[side] or "front" --The final number means that it will
  858. if final then final = 0 else final = 1 end --drop a whole stack at the end
  859. local allowSkip = allowSkip or (final == 0) --This will allow drop(side,t/f, rednetConnected)
  860. count()
  861. if doRefuel then
  862. for i=1, 16 do
  863. if slot[i][1] == 2 then
  864. turtle.select(i); turtle.refuel()
  865. end
  866. end
  867. turtle.select(1)
  868. end
  869. if side == "right" then turnTo(1) end
  870. if side == "left" then turnTo(3) end
  871. local whereDetect, whereDrop1, whereDropAll
  872. local _1 = slot[1][2] - final --All but one if final, all if not final
  873. if side == "top" then
  874. whereDetect = turtle.detectUp ; whereDrop = turtle.dropUp
  875. elseif side == "bottom" then
  876. whereDetect = turtle.detectDown ; whereDrop = turtle.dropDown
  877. else
  878. whereDetect = turtle.detect; whereDrop = turtle.drop
  879. end
  880. local function waitDrop(val) --This will just drop, but wait if it can't
  881. val = val or 64
  882. local try = 1
  883. while not whereDrop(val) do
  884. print("Chest Full, Try "..try)
  885. try = try + 1
  886. sleep(2)
  887. end
  888. end
  889. repeat
  890. local detected = whereDetect()
  891. if detected then
  892. waitDrop(_1)
  893. for i=2, 16 do
  894. if turtle.getItemCount(i) > 0 then
  895. turtle.select(i)
  896. waitDrop()
  897. end
  898. end
  899. elseif not allowSkip then
  900. print("Waiting for chest placement place a chest to continue")
  901. while not whereDetect() do
  902. sleep(1)
  903. end
  904. end
  905. until detected or allowSkip
  906. if not allowSkip then totals.cobble = totals.cobble - 1 end
  907. turtle.select(1)
  908. turnTo(0)
  909. end
  910. function dropOff() --Not local because called in mine()
  911. local currX,currZ,currY,currFacing = xPos, zPos, yPos, facing
  912. goto(0,1,1,2)
  913. drop(dropSide,false)
  914. mine(false,false,true, false)
  915. goto(1,1,1, 0)
  916. goto(currX,currZ,currY,currFacing)
  917. end
  918. function bedrock()
  919. if checkFuel() == 0 then error("No Fuel",0) end
  920. local origin = {x = xPos, y = yPos, z = zPos}
  921. print("Bedrock Detected")
  922. if turtle.detectUp() then
  923. print("Block Above")
  924. local var
  925. if facing == 0 then var = 2 elseif facing == 2 then var = 0 else error("Was facing left or right on bedrock") end
  926. goto(xPos,zPos,yPos,var)
  927. for i=1, relxPos do mine(true,true); end
  928. end
  929. goto(0,1,1,2)
  930. drop(dropSide, true)
  931. display()
  932. print("\nFound bedrock at these coordinates: ")
  933. print(origin.x," Was position in row\n",origin.z," Was row in layer\n",origin.y," Blocks down from start")
  934. error("",0)
  935. end
  936. -------------------------------------------------------------------------------------
  937. --Pre-Mining Stuff dealing with session persistence
  938. local doDigDown, doDigUp = (lastHeight ~= 1), false --Used in lastHeight
  939. if not restoreFound then
  940. --Check if it is a mining turtle
  941. if not isMiningTurtle then
  942. local a, b = turtle.dig()
  943. if a then mined = mined + 1; isMiningTurtle = true
  944. elseif b == "Nothing to dig with" then
  945. print("This is not a mining turtle. To make a mining turtle, craft me together with a diamond pickaxe")
  946. error("",0)
  947. end
  948. end
  949. while not turtle.forward() do end
  950. else digUp(); digDown() end --Get it into the quarry
  951. 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.
  952. gpsSecondPos = {gps.locate(gpsTimeout)} --Note: Does not run this if it has already been restarted.
  953. end
  954. if restoreFound then
  955. if gotoX then
  956. goto(gotoX,gotoZ,gotoY,gotoFacing)
  957. end
  958. local func
  959. if rowCheck == "left" then func = right else func = left end
  960. if endRow == 1 then
  961. mine()
  962. func()
  963. elseif endRow == 2 then
  964. func()
  965. end
  966. end
  967. if y ~= 0 and not restoreFound then down() end
  968. --Mining Loops
  969. turtle.select(1)
  970. while layersDone <= y do -------------Height---------
  971. moved = moved + 1 --To account for the first position in row as "moved"
  972. if not restoreFound then rowCheck = "right" end
  973. relativeXCalc()
  974. while zPos <= z do -------------Width----------
  975. while relxPos < x do ------------Length---------
  976. mine()
  977. end ---------------Length End-------
  978. if zPos ~= z then
  979. local func
  980. if rowCheck == "right" and zPos ~= z then --Swithcing to next row
  981. func = right; rowCheck = "left"; else func = left; rowCheck = "right" end --Which way to turn
  982. func()
  983. endRow = 1
  984. mine()
  985. endRow = 2
  986. func()
  987. endRow = 0
  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. endRow = 1
  1015. mine(doDigDown,doDigUp)
  1016. endRow = 2
  1017. func()
  1018. endRow = 0
  1019. else break
  1020. end
  1021. end ---------------Width End--------
  1022. goto(1,1,yPos,0)
  1023. end
  1024. if doDigDown then
  1025. if inverted then
  1026. digUp()
  1027. else
  1028. digDown()
  1029. end
  1030. end
  1031. goto(0,1,1,2)
  1032.  
  1033. --Output to a chest or sit there
  1034. drop(dropSide, true)
  1035. --Display was moved above to be used in bedrock function
  1036. display()
  1037. --Log current mining run
  1038. logMiningRun(logExtension)
  1039.  
  1040. --Cleanup
  1041. turtle.getFuelLevel = getFuel
Add Comment
Please, Sign In to add comment