Advertisement
civilwargeeky

Quarry 3.4.1 Ore Quarry Hack

Feb 24th, 2014
1,633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 50.12 KB | None | 0 0
  1. --[[
  2. Version 3.4.1 Selection Hack
  3. Recent Changes:
  4.   Bedrock check only runs if there is a block in the way
  5.   Added New Rednet Support
  6.   Rednet messages work better
  7.   New Arguments!
  8.     -atChest [force] Using this with -resume will tell the turtle that it is at its chest, and needs to go back to where it was
  9.     -maxTries [number 1-9000] This is the number of times the turtle will try to mine something before it checks for bedrock
  10.   Arguments are no longer ignored if you use "-default", you just won't be prompted for anything.
  11.   Boolean (t/f) arguments now accept "yes" as well as "true"
  12. ]]
  13. --Defining things
  14. civilTable = nil; _G.civilTable = {}; setmetatable(civilTable, {__index = _G}); setfenv(1,civilTable)
  15. -------Defaults for Arguments----------
  16. --Arguments assignable by text
  17. x,y,z = 3,3,3 --These are just in case tonumber fails
  18. inverted = false --False goes from top down, true goes from bottom up [Default false]
  19. rednetEnabled = false --Default rednet on or off  [Default false]
  20. --Arguments assignable by tArgs
  21. dropSide = "front" --Side it will eject to when full or done [Default "front"]
  22. careAboutResources = true --Will not stop mining once inventory full if false [Default true]
  23. doCheckFuel = true --Perform fuel check [Default true]
  24. doRefuel = false --Whenever it comes to start location will attempt to refuel from inventory [Default false]
  25. invCheckFreq = 10 --Will check for inventory full every <-- moved spaces [Default 10]
  26. keepOpen = 1 --How many inventory slots it will attempt to keep open at all times [Default 1]
  27. fuelSafety = "moderate" --How much fuel it will ask for: safe, moderate, and loose [Default moderate]
  28. saveFile = "Civil_Quarry_Restore" --Where it saves restore data [Default "Civil_Quarry_Restore"]
  29. doBackup = true --If it will keep backups for session persistence [Default true]
  30. 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]
  31. maxTries = 50 --How many times turtle will try to dig a block before it "counts" bedrock [Default 50]
  32. gpsEnabled = false -- If option is enabled, will attempt to find position via GPS api [Default false]
  33. gpsTimeout = 3 --The number of seconds the program will wait to get GPS coords. Not in arguments [Default 3]
  34. logging = true --Whether or not the turtle will log mining runs. [Default ...still deciding]
  35. logFolder = "Quarry_Logs" --What folder the turtle will store logs in [Default "Quarry_Logs"]
  36. logExtension = "" --The extension of the file (e.g. ".txt") [Default ""]
  37. startDown = 0 --How many blocks to start down from the top of the mine [Default 0]
  38. enderChestEnabled = false --Whether or not to use an ender chest [Default false]
  39. enderChestSlot = 16 --What slot to put the ender chest in [Default 16]
  40. hack = true --Hack to selectively mine blocks
  41. --Standard number slots for fuel (you shouldn't care)
  42. fuelTable = { --Will add in this amount of fuel to requirement.
  43. safe = 1000,
  44. moderate = 200,
  45. loose = 0 } --Default 1000, 200, 0
  46. --Standard rednet channels
  47. channels = {
  48. send = os.getComputerID() + 1  ,
  49. receive = os.getComputerID() + 101 ,
  50. confirm = "Turtle Quarry Receiver",
  51. message = "Civil's Quarry",
  52. }
  53.  
  54. local help_paragraph = [[
  55. Welcome!: Welcome to quarry help. Below are help entries for all parameters. Examples and tips are at the bottom.
  56. -Default: This will force no prompts. If you use this and nothing else, only defaults will be used.
  57. -dim: [length] [width] [height] This sets the dimensions for the quarry
  58. -invert: [t/f] If true, quarry will be inverted (go up instead of down)
  59. -rednet: [t/f] If true and you have a wireless modem on the turtle, will attempt to make a rednet connection for sending important information to a screen
  60. -restore / -resume: If your quarry stopped in the middle of its run, use this to resume at the point where the turtle was. Not guarenteed to work properly. For more accurate location finding, check out the -GPS parameter
  61. -atChest: [force] This is for use with "-restore," this will tell the restarting turtle that it is at its home chest, so that if it had gotten lost, it now knows where it is.
  62. -doRefuel: [t/f] If true, the turtle will refuel itself with coal and planks it finds on its mining run
  63. -doCheckFuel: [t/f] If you for some reason don't want the program to check fuel usage, set to false. This is honestly a hold-over from when the refueling algorithm was awful...
  64. -chest: [side] This specifies what side the chest at the end will be on. You can say "top", "bottom", "front", "left", or "right"
  65. -enderChest: This one is special. If you use "-enderChest true" then it will use an enderChest in the default slot. However, you can also do "-enderChest [slot]" then it will take the ender chest from whatever slot you tell it to. Like 7... or 14... or whatever.
  66. -GPS: [force] If you use "-GPS" and there is a GPS network, then the turtle will record its first two positions to precisly calculate its position if it has to restart. This will only take two GPS readings
  67. -sendChannel: [number] This is what channel your turtle will send rednet messages on
  68. -receiveChannel: [number] This is what channel your turtle will receive rednet messages on
  69. -startY: [current Y coord] Randomly encountering bedrock? This is the parameter for you! Just give it what y coordinate you are at right now. If it is not within bedrock range, it will never say it found bedrock
  70. -maxTries: [number] This is the number of times the turtle will try to dig before deciding its run into bedrock.
  71. -logging: [t/f] If true, will record information about its mining run in a folder at the end of the mining run
  72. -doBackup: [t/f] If false, will not back up important information and cannot restore, but will not make an annoying file (Actually I don't really know why anyone would use this...)
  73. -saveFile: [word] This is what the backup file will be called
  74. -logFolder: [word] The folder that quarry logs will be stored in
  75. -logExtension: [word] The extension given to each quarry log (e.g. ".txt" or ".notepad" or whatever)
  76. -invCheckFreq: [number] This is how often the turtle will check if it has the proper amount of slots open
  77. -keepOpen: [number] This is the number of the slots the turtle will make sure are open. It will check every invCheckFreq blocks
  78. -careAboutResources: [t/f] Who cares about the materials! If set to false, it will just keep mining when its inventory is full
  79. -startDown: [number] If you set this, the turtle will go down this many blocks from the start before starting its quarry
  80.   =
  81.   C _ |
  82.       |
  83.       |
  84.       |
  85.       |_ _ _ _ >
  86. -manualPos: [xPos] [zPos] [yPos] [facing] This is for advanced use. If the server reset when the turtle was in the middle of a 100x100x100 quarry, fear not, you can now manually set the position of the turtle. yPos is always positive. The turtle's starting position is 0, 1, 1, 0. Facing is measured 0 - 3. 0 is forward, and it progresses clockwise. Example- "-manualPos 65 30 30 2"
  87. -help: Thats what this is :D
  88. Examples: Everything below is examples and tips for use
  89. Important Note:
  90.  None of the above parameters are necessary. They all have default values, and the above are just if you want to change them.
  91. Examples [1]:
  92.  Want to just start a quarry from the interface, without going through menus? It's easy! Just use some parameters. Assume you called the program "quarry." To start a 10x6x3 quarry, you just type in "quarry -dim 10 6 3 -default".
  93.   You just told it to start a quarry with dimensions 10x6x3, and "-default" means it won't prompt you about invert or rednet. Wasn't that easy?
  94. Examples [2]:
  95.   Okay, so you've got the basics of this now, so if you want, you can type in really long strings of stuff to make the quarry do exactly what you want. Now, say you want a 40x20x9, but you want it to go down to diamond level, and you're on the surface (at y = 64). You also want it to send rednet messages to your computer so you can see how its doing.
  96. Examples [2] [cont.]:
  97.   Oh yeah! You also want it to use an ender chest in slot 12 and restart if the server crashes. Yeah, you can do that. You would type
  98.   "quarry -dim 40x20x9 -invert false -startDown 45 -rednet true -enderChest 12 -restore"
  99.   BAM. Now you can just let that turtle do it's thing
  100. Tips:
  101.  The order of the parameters doesn't matter. "quarry -invert false -rednet true" is the same as "quarry -rednet true -invert false"
  102.  
  103.   Capitalization doesn't matter. "quarry -iNVErt FALSe" does the same thing as "quarry -invert false"
  104. Tips [cont.]:
  105.  For [t/f] parameters, you can also use "yes" and "no" so "quarry -invert yes"
  106.  
  107.  For [t/f] parameters, it only cares about the first letter. So you can use "quarry -invert t" or "quarry -invert y"
  108. Tips [cont.]:
  109.  If you are playing with fuel turned off, the program will automatically change settings for you so you don't have to :D
  110.  
  111.   If you want, you can load this program onto a computer, and use "quarry -help" so you can have help with the parameters whenever you want.
  112. Internal Config:
  113.   At the top of this program is an internal configuration file. If there is some setup that you use all the time, you can just change the config value at the top and run "quarry -default" for a quick setup.
  114.  
  115.   You can also use this if there are settings that you don't like the default value of.
  116. ]]
  117.  
  118. --Parsing help for display
  119. --[[The way the help table works:
  120. All help indexes are numbered. There is a help[i].title that contains the title,
  121. and the other lines are in help[i][1] - help[i][#help[i] ]
  122. Different lines (e.g. other than first) start with a space.
  123. As of now, the words are not wrapped, fix that later]]
  124. local help = {}
  125. local i = 0
  126. local titlePattern = ".-%:" --Find the beginning of the line, then characters, then a ":"
  127. local textPattern = "%:.+" --Find a ":", then characters until the end of the line
  128. for a in help_paragraph:gmatch("\n?.-\n") do --Matches in between newlines
  129. local current = string.sub(a,1,-2).."" --Concatenate Trick
  130. if string.sub(current,1,1) ~= " " then
  131. i = i + 1
  132. help[i] = {}
  133. help[i].title = string.sub(string.match(current, titlePattern),1,-2)..""
  134. help[i][1] = string.sub(string.match(current,textPattern) or " ",3,-1)
  135. elseif string.sub(current,1,1) == " " then
  136. table.insert(help[i], string.sub(current,2, -1).."")
  137. end
  138. end
  139.  
  140.  
  141. local supportsRednet = (peripheral.wrap("right") ~= nil)
  142.  
  143. local tArgs = {...}
  144. --You don't care about these
  145.       xPos,yPos,zPos,facing,percent,mined,moved,relxPos, rowCheck, connected, isInPath, layersDone, attacked, startY, chestFull, gotoDest, atChest
  146.     = 0,   1,   1,   0,     0,      0,    0,    1,       "right",  false,     true,     1,          0,        0,      false,     "",       false
  147.    
  148. local foundBedrock = false
  149.  
  150. local totals = {cobble = 0, fuel = 0, other = 0} -- Total for display (cannot go inside function)
  151. local function count() --Done any time inventory dropped and at end
  152. slot = {}        --1: Cobble 2: Fuel 3:Other
  153. for i=1, 16 do   --[1] is type, [2] is number
  154. slot[i] = {}
  155. slot[i][2] = turtle.getItemCount(i)
  156. end
  157. slot[1][1] = 1   -- = Assumes Cobble/Main
  158. for i=1, 16 do   --Cobble Check
  159. turtle.select(i)
  160. if turtle.compareTo(1)  then
  161. slot[i][1] = 1
  162. totals.cobble = totals.cobble + slot[i][2]
  163. elseif turtle.refuel(0) then
  164. slot[i][1] = 2
  165. totals.fuel = totals.fuel + slot[i][2]
  166. else
  167. slot[i][1] = 3
  168. totals.other = totals.other + slot[i][2]
  169. end
  170. end
  171. turtle.select(1)
  172. end
  173.  
  174. local getFuel, checkFuel
  175. if turtle then
  176.   getFuel = turtle.getFuelLevel  --This is for cleanup at the end
  177.   do --Common variable name...
  178.   local flag = turtle.getFuelLevel() == "unlimited"--Unlimited screws up my calculations
  179.   if flag then --Fuel is disabled
  180.     turtle.getFuelLevel = function() return math.huge end --Infinite Fuel
  181.   end --There is no "else" because it will already return the regular getFuel
  182.   end
  183.   checkFuel = turtle.getFuelLevel --Just an alias for backwards compat
  184. end
  185.  
  186.  -----------------------------------------------------------------
  187. --Input Phase
  188. local function screen(xPos,yPos)
  189. xPos, yPos = xPos or 1, yPos or 1
  190. term.setCursorPos(xPos,yPos); term.clear(); end
  191. local function screenLine(xPos,yPos)
  192. term.setCursorPos(xPos,yPos); term.clearLine(); end
  193.  
  194. screen(1,1)
  195. print("----- Welcome to Quarry! -----")
  196. print("")
  197.  
  198. local sides = {top = "top", right = "right", left = "left", bottom = "bottom", front = "front"} --Used to whitelist sides
  199. local changedT, tArgsWithUpper = {}, {}
  200. changedT.new = function(key, value) table.insert(changedT,{key, value}) end --Numeric list of lists
  201. local function capitalize(text) return (string.upper(string.sub(text,1,1))..string.sub(text,2,-1)) end
  202. for i=1, #tArgs do tArgsWithUpper[i] = tArgs[i]; tArgsWithUpper[tArgsWithUpper[i]] = i; tArgs[i] = tArgs[i]:lower(); tArgs[tArgs[i]] = i end --My signature key-value pair system, now with upper
  203.  
  204. local restoreFound, restoreFoundSwitch = false --Initializing so they are in scope
  205. function addParam(name, displayText, formatString, forcePrompt, trigger, variableOverride) --To anyone that doesn't understand this very well, probably not your best idea to go in here.
  206.   if trigger == nil then trigger = true end --Defaults to being able to run
  207.   if not trigger then return end --This is what the trigger is for. Will not run if trigger not there
  208.   if restoreFoundSwitch or tArgs["-default"] then forcePrompt = false end --Don't want to prompt if these
  209.   local toGetText = name:lower() --Because all params are now lowered
  210.   local formatType = formatString:match("^%a+"):lower() or error("Format String Unknown: "..formatString) --Type of format string
  211.   local args = formatString:sub(({formatString:find(formatType)})[2] + 2).."" --Everything in formatString but the type and space
  212.   local variable = variableOverride or name --Goes first to the override for name
  213.   local func = loadstring("return "..variable)
  214.   setfenv(func,getfenv(1))
  215.   local originalValue = assert(func)() --This is the default value, for checking to add to changed table
  216.   if originalValue == nil then error("From addParam, \""..variable.."\" returned nil",2) end --I may have gotten a wrong variable name
  217.   local givenValue, toRet --Initializing for use
  218.   if tArgs["-"..toGetText] then
  219.     givenValue = tArgsWithUpper[tArgs["-"..toGetText]+1] --This is the value after the desired parameter
  220.   elseif forcePrompt then
  221.     write(displayText.."? ")
  222.     givenValue = io.read()
  223.   end
  224.   if formatType == "force" then --This is the one exception. Should return true if givenValue is nothing
  225.     toRet = (tArgs["-"..toGetText] and true) or false --Will return true if param exists, otherwise false
  226.   end
  227.   if not (givenValue or toRet) then return end --Don't do anything if you aren't given anything. Leave it as default, except for "force"
  228.   if formatType == "boolean" then --All the format strings will be basically be put through a switch statement
  229.     toRet = givenValue:sub(1,1):lower() == "y" or givenValue:sub(1,1):lower() == "t" --Accepts true or yes
  230.     if formatString == "boolean special" then
  231.       toRet = givenValue:sub(1,1):lower() ~= "n" and givenValue:sub(1,1):lower() ~= "f" --Accepts anything but false or no
  232.     end
  233.   elseif formatType == "string" then
  234.     toRet = givenValue:match("^[%w%.]+") --Basically anything not a space or control character etc
  235.   elseif formatType == "number" then
  236.     toRet = tonumber(givenValue) --Note this is a local, not the above so we don't change anything
  237.     if not toRet then return end --We need a number... Otherwise compare errors
  238.     toRet = math.abs(math.floor(toRet)) --Get proper integers
  239.     local startNum, endNum = formatString:match("(%d+)%-(%d+)") --Gets range of numbers
  240.     startNum, endNum = tonumber(startNum), tonumber(endNum)
  241.     if not ((toRet >= startNum) and (toRet <= endNum)) then return end --Can't use these
  242.   elseif formatType == "side" then
  243.     local exclusionTab = {} --Ignore the wizardry here. Just getting arguments without format string
  244.     for a in args:gmatch("%S+") do exclusionTab[a] = true end --This makes a list of the sides to not include
  245.     if not exclusionTab[givenValue] then toRet = sides[givenValue] end --If side is not excluded
  246.   elseif formatType == "list" then
  247.     toRet = {}
  248.     for a in args:gmatch("[^,]") do
  249.       table.insert(toRet,a)
  250.     end
  251.   elseif formatType == "force" then --Do nothing, everything is already done
  252.   else error("Improper formatType",2)
  253.   end
  254.   if toRet == nil then return end --Don't want to set variables to nil... That's bad
  255.   tempParam = toRet --This is what loadstring will see :D
  256.   local func = loadstring(variable.." = tempParam")
  257.   setfenv(func, getfenv(1))
  258.   func()
  259.   tempParam = nil --Cleanup of global
  260.   if toRet ~= originalValue then
  261.     changedT.new(displayText, tostring(toRet))
  262.   end
  263.   return toRet
  264. end
  265.  
  266. --Check if it is a turtle
  267. if not(turtle or tArgs["help"] or tArgs["-help"] or tArgs["-?"] or tArgs["?"]) then --If all of these are false then
  268.   print("This is not a turtle, you might be looking for the \"Companion Rednet Program\" \nCheck My forum thread for that")
  269.   print("Press 'q' to quit, or any other key to start help ")
  270.   if ({os.pullEvent("char")})[2] ~= "q" then tArgs.help = true else error("",0) end
  271. end
  272.  
  273. if tArgs["help"] or tArgs["-help"] or tArgs["-?"] or tArgs["?"] then
  274. print("You have selected help, press any key to continue"); print("Use arrow keys to naviate, q to quit"); os.pullEvent("key")
  275. local pos = 1
  276. local key = 0
  277. while pos <= #help and key ~= keys.q do
  278. if pos < 1 then pos = 1 end
  279. screen(1,1)
  280. print(help[pos].title)
  281. for a=1, #help[pos] do print(help[pos][a]) end
  282. repeat
  283. _, key = os.pullEvent("key")
  284. until key == 200 or key == 208 or key == keys.q
  285. if key == 200 then pos = pos - 1 end
  286. if key == 208 then pos = pos + 1 end
  287. end
  288. error("",0)
  289. end
  290.  
  291. --Saving
  292. addParam("doBackup", "Backup Save File", "boolean")
  293. addParam("saveFile", "Save File Name", "string")
  294.  
  295. restoreFound = fs.exists(saveFile)
  296. restoreFoundSwitch = (tArgs["-restore"] or tArgs["-resume"] or tArgs["-atchest"]) and restoreFound
  297. if restoreFoundSwitch then
  298.   local file = fs.open(saveFile,"r")
  299.   local test = file.readAll() ~= ""
  300.   file.close()
  301.   if test then
  302.     os.run(getfenv(1),saveFile)
  303.     if gpsEnabled then --If it had saved gps coordinates
  304.       print("Found GPS Start Coordinates")
  305.       local currLoc = {gps.locate(gpsTimeout)} or {}
  306.       local backupPos = {xPos, yPos, zPos} --This is for comparing to later
  307.       if #currLoc > 0 and #gpsStartPos > 0 and #gpsSecondPos > 0 then --Cover all the different positions I'm using
  308.         print("GPS Position Successfully Read")
  309.         if currLoc[1] == gpsStartPos[1] and currLoc[3] == gpsStartPos[3] then --X coord, y coord, z coord in that order
  310.           xPos, yPos, zPos = 0,1,1
  311.           if facing ~= 0 then turnTo(0) end
  312.           print("Is at start")
  313.         else
  314.           if inverted then --yPos setting
  315.           ------------------------------------------------FIX THIS
  316.           end
  317.           local function copyTable(tab) local toRet = {}; for a, b in pairs(tab) do toRet[a] = b end; return toRet end
  318.           local a, b = copyTable(gpsStartPos), copyTable(gpsSecondPos) --For convenience
  319.           if b[3] - a[3] == -1 then--If went north (-Z)
  320.             a[1] = a[1] - 1 --Shift x one to west to create a "zero"
  321.             xPos, zPos = -currLoc[3] + a[3], currLoc[1] + -a[1]
  322.           elseif b[1] - a[1] == 1 then--If went east (+X)
  323.             a[3] = a[3] - 1 --Shift z up one to north to create a "zero"
  324.             xPos, zPos = currLoc[1] + -a[1], currLoc[3] + -a[3]
  325.           elseif b[3] - a[3] == 1 then--If went south (+Z)
  326.             a[1] = a[1] + 1 --Shift x one to east to create a "zero"
  327.             xPos, zPos = currLoc[3] + a[3], -currLoc[1] + a[3]
  328.           elseif b[1] - a[1] == -1 then--If went west (-X)
  329.             a[3] = a[3] + 1 --Shift z down one to south to create a "zero"
  330.             xPos, zPos = -currLoc[1] + a[1], -currLoc[3] + a[3]
  331.           else
  332.             print("Improper Coordinates")
  333.             print("GPS Locate Failed, Using Standard Methods")        ----Maybe clean this up a bit to use flags instead.
  334.           end  
  335.         end
  336.         print("X Pos: ",xPos)
  337.         print("Y Pos: ",yPos)
  338.         print("Z Pos: ",zPos)
  339.         print("Facing: ",facing)
  340.         for i=1, 3, 2 do --We want 1 and 3, but 2 could be coming back to start.
  341.           if backupPos[i] ~= currLoc[i] then
  342.             events = {} --We want to remove event queue if not in proper place, so won't turn at end of row or things.
  343.           end
  344.         end
  345.       else
  346.         print("GPS Locate Failed, Using Standard Methods")
  347.       end    
  348.     print("Restore File read successfully. Starting in 3"); sleep(3)
  349.     end
  350.   else
  351.     fs.delete(saveFile)
  352.     print("Restore file was empty, sorry, aborting")
  353.     error("",0)
  354.   end
  355. else --If turtle is just starting
  356.   events = {} --This is the event queue :D
  357.   originalFuel = checkFuel() --For use in logging. To see how much fuel is REALLY used
  358. end
  359.  
  360. --Dimensions
  361. if tArgs["-dim"] then local num = tArgs["-dim"];
  362. x = tonumber(tArgs[num + 1]) or x; z = tonumber(tArgs[num + 2]) or z; y = tonumber(tArgs[num + 3]) or y
  363. elseif not (tArgs["-default"] or restoreFoundSwitch) then
  364. print("What dimensions?")
  365. print("")
  366. --This will protect from negatives, letters, and decimals
  367. term.write("Length? ")
  368. x = math.floor(math.abs(tonumber(io.read()) or x))
  369. term.write("Width? ")
  370. z = math.floor(math.abs(tonumber(io.read()) or z))
  371. term.write("Height? ")
  372. y = math.floor(math.abs(tonumber(io.read()) or y))
  373. changedT.new("Length",x); changedT.new("Width",z); changedT.new("Height",y)
  374. end
  375. --Invert
  376. addParam("invert", "Inverted","boolean", true, nil, "inverted")
  377. addParam("startDown","Start Down","number 1-256")
  378. --Inventory
  379. addParam("chest", "Chest Drop Side", "side front", nil, nil, "dropSide")
  380. addParam("enderChest","Ender Chest Enabled","boolean special", nil, nil, "enderChestEnabled") --This will accept anything (including numbers) thats not "f" or "n"
  381. addParam("enderChest", "Ender Chest Slot", "number 1-16", nil, nil, "enderChestSlot") --This will get the number slot if given
  382. --Rednet
  383. addParam("rednet", "Rednet Enabled","boolean",true, supportsRednet, "rednetEnabled")
  384. addParam("gps", "GPS Location Services", "force", nil, (not restoreFoundSwitch) and supportsRednet, "gpsEnabled" ) --Has these triggers so that does not record position if restarted.
  385. if gpsEnabled and not restoreFoundSwitch then
  386.   gpsStartPos = {gps.locate(gpsTimeout)} --Stores position in array
  387.   gpsEnabled = #gpsStartPos > 0 --Checks if location received properly. If not, position is not saved
  388. end
  389. addParam("sendChannel", "Rednet Send Channel", "number 1-65535", false, supportsRednet, "channels.send")
  390. addParam("receiveChannel","Rednet Receive Channel", "number 1-65535", false, supportsRednet, "channels.receive")
  391. --Fuel
  392. addParam("doRefuel", "Refuel from Inventory","boolean", nil, turtle.getFuelLevel() ~= math.huge) --math.huge due to my changes
  393. addParam("doCheckFuel", "Check Fuel", "boolean", nil, turtle.getFuelLevel() ~= math.huge)
  394. --Logging
  395. addParam("logging", "Logging", "boolean")
  396. addParam("logFolder", "Log Folder", "string")
  397. addParam("logExtension","Log Extension", "string")
  398. --Misc
  399. addParam("startY", "Start Y","number 1-256")
  400. addParam("invCheckFreq","Inventory Check Frequency","number 1-342")
  401. addParam("keepOpen", "Slots to Keep Open", "number 1-15")
  402. addParam("careAboutResources", "Care About Resources","boolean")
  403. addParam("maxTries","Tries Before Bedrock", "number 1-9001")
  404.  
  405. addParam("hack", "Conditional Mining", "boolean", true)
  406. --Manual Position
  407. if tArgs["-manualpos"] then --Gives current coordinates in xPos,zPos,yPos, facing
  408.   local a = tArgs["-manualpos"]
  409.   xPos, zPos, yPos, facing = tonumber(tArgs[a+1]) or xPos, tonumber(tArgs[a+2]) or zPos, tonumber(tArgs[a+3]) or yPos, tonumber(tArgs[a+4]) or facing
  410.   changedT.new("xPos",xPos); changedT.new("zPos",zPos); changedT.new("yPos",yPos); changedT.new("facing",facing)
  411.   restoreFoundSwitch = true --So it doesn't do beginning of quarry behavior
  412. end
  413. if addParam("atChest", "Is at Chest", "force") then --This sets position to 0,1,1, facing forward, and queues the turtle to go back to proper row.
  414.   local neededLayer = math.floor((yPos+1)/3)*3-1 --Make it a proper layer, +- because mining rows are 2, 5, etc.
  415.   if neededLayer > 2 and neededLayer%3 ~= 2 then --If turtle was not on a proper mining layer
  416.     print("Last known pos was not in proper layer, restarting quarry")
  417.     sleep(4)
  418.     neededLayer = 2
  419.   end
  420.   xPos, zPos, yPos, facing, rowCheck, layersDone = 0,1,1, 0, "right", math.ceil(neededLayer/3)
  421.   events = {{"goto",1,1,neededLayer, 0}}
  422. end
  423.  
  424.  
  425. local function saveProgress(extras) --Session persistence
  426. exclusions = { modem = true, }
  427. if doBackup then
  428. local toWrite = ""
  429. for a,b in pairs(getfenv(1)) do
  430.   if not exclusions[a] then
  431.       --print(a ,"   ", b, "   ", type(b)) --Debug
  432.     if type(b) == "string" then b = "\""..b.."\"" end
  433.     if type(b) == "table" then b = textutils.serialize(b) end
  434.     if type(b) ~= "function" then
  435.       toWrite = toWrite..a.." = "..tostring(b).."\n"
  436.     end
  437.   end
  438. end
  439. toWrite = toWrite.."doCheckFuel = false\n" --It has already used fuel, so calculation unnesesary
  440. local file
  441. repeat
  442.   file = fs.open(saveFile,"w")
  443. until file --WHY DOES IT SAY ATTEMPT TO INDEX NIL!!!
  444. file.write(toWrite)
  445. if type(extras) == "table" then
  446.   for a, b in pairs(extras) do
  447.     file.write(a.." = "..tostring(b))
  448.   end
  449. end
  450. file.close()
  451. end
  452. end
  453.  
  454. local area = x*z
  455. local volume = x*y*z
  456. local lastHeight = y%3
  457. layers = math.ceil(y/3)
  458. local yMult = layers --This is basically a smart y/3 for movement
  459. local moveVolume = (area * yMult) --Kept for display percent
  460. --Calculating Needed Fuel--
  461. local exStack = numberOfStacksPerRun --Expected stacks of items before full
  462. neededFuel = yMult * x * z + --This is volume it will run through
  463.       (startDown + y)*(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
  464.       (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
  465.       --Original equation: x*z*y/3 + y * 2 + (x+z) * y/3 + (x + z + y) * (1/64*8)
  466. neededFuel = math.ceil(neededFuel)
  467.  
  468. --Getting Fuel
  469. if doCheckFuel and checkFuel() < neededFuel then
  470. neededFuel = neededFuel + fuelTable[fuelSafety] --For safety
  471.   print("Not enough fuel")
  472.   print("Current: ",checkFuel()," Needed: ",neededFuel)
  473.   print("Starting SmartFuel...")
  474.   sleep(2) --So they can read everything.
  475.   term.clear()
  476.   local oneFuel, neededFuelItems
  477.   local currSlot = 0
  478.   local function output(text, x, y) --For displaying fuel
  479.     local currX, currY = term.getCursorPos()
  480.     term.setCursorPos(x,y)
  481.     term.clearLine()
  482.     term.write(text)
  483.     term.setCursorPos(currX,currY)
  484.     end
  485.   local function roundTo(num, target) --For stacks of fuel
  486.     if num >= target then return target elseif num < 0 then return 0 else return num end
  487.   end
  488.   local function updateScreen()
  489.     output("Welcome to SmartFuel! Now Refueling...", 1,1)
  490.     output("Currently taking fuel from slot "..currSlot,1,2)
  491.     output("Current single fuel: "..tostring(oneFuel or 0),1,3)
  492.     output("Current estimate of needed fuel: ",1,4)
  493.     output("Single Items: "..math.ceil(neededFuelItems or 0),4,5)
  494.     output("Stacks:       "..math.ceil((neededFuelItems or 0) / 64),4,6)
  495.     output("Needed Fuel: "..tostring(neededFuel),1,12)
  496.     output("Current Fuel: "..tostring(checkFuel()),1,13)
  497.   end
  498.   while checkFuel() <= neededFuel do
  499.     currSlot = currSlot + 1
  500.     turtle.select(currSlot)
  501.     updateScreen()
  502.     while turtle.getItemCount(currSlot) == 0 do sleep(1.5) end
  503.     repeat
  504.       local previous = checkFuel()
  505.       turtle.refuel(1)
  506.       oneFuel = checkFuel() - previous
  507.       updateScreen()
  508.     until (oneFuel or 0) > 0 --Not an if to prevent errors if fuel taken out prematurely.
  509.     neededFuelItems = (neededFuel - checkFuel()) / oneFuel
  510.     turtle.refuel(math.ceil(roundTo(neededFuelItems, 64))) --Change because can only think about 64 at once.
  511.     if turtle.getItemCount(roundTo(currSlot + 1, 16)) == 0 then --Resets if no more fuel
  512.       currSlot = 0
  513.     end
  514.     neededFuelItems = (neededFuel - checkFuel()) / oneFuel
  515.   end
  516. end
  517. --Ender Chest Obtaining
  518. if enderChestEnabled then
  519.     if restoreFoundSwitch and turtle.getItemCount(enderChestSlot) == 0 then --If the turtle was stopped while dropping off items.
  520.       turtle.select(enderChestSlot)
  521.       turtle.dig()
  522.       turtle.select(1)
  523.     end
  524.   while turtle.getItemCount(enderChestSlot) ~= 1 do
  525.     screen(1,1)
  526.     print("You have decided to use an Ender Chest!")
  527.     print("Please place one Ender Chest in slot ",enderChestSlot)
  528.     sleep(1)
  529.   end
  530.   print("Ender Chest in slot ",enderChestSlot, " checks out")
  531.   sleep(2)
  532. end
  533. --Initial Rednet Handshake
  534. if rednetEnabled then
  535. screen(1,1)
  536. print("Rednet is Enabled")
  537. print("The Channel to open is "..channels.send)
  538. modem = peripheral.wrap("right")
  539. modem.open(channels.receive)
  540. local i = 0
  541.   repeat
  542.     local id = os.startTimer(3)
  543.     i=i+1
  544.     print("Sending Initial Message "..i)
  545.     modem.transmit(channels.send, channels.receive, channels.message)
  546.     local message
  547.     repeat
  548.       local event, idCheck, channel,_,locMessage, distance = os.pullEvent()
  549.       message = locMessage
  550.     until (event == "timer" and idCheck == id) or (event == "modem_message" and channel == channels.receive and message == channels.confirm)
  551.   until message == channels.confirm
  552. connected = true
  553. print("Connection Confirmed!")
  554. sleep(1.5)
  555. end
  556. function biometrics(isAtBedrock)
  557.   local toSend = { label = os.getComputerLabel() or "No Label", id = os.getComputerID(),
  558.     percent = percent, relxPos = relxPos, zPos = zPos, xPos = xPos, yPos = yPos,
  559.     layersDone = layersDone, x = x, z = z, layers = layers,
  560.     openSlots = getNumOpenSlots(), mined = mined, moved = moved,
  561.     chestFull = chestFull, isAtChest = (xPos == 0 and yPos == 1 and zPos == 1),
  562.     isGoingToNextLayer = (gotoDest == "layerStart"), foundBedrock = foundBedrock,
  563.     fuel = turtle.getFuelLevel(), volume = volume,
  564.     }
  565.   modem.transmit(channels.send, channels.receive, textutils.serialize(toSend))
  566.   id = os.startTimer(0.1)
  567.   local event, message
  568.   repeat
  569.     local locEvent, idCheck, confirm, _, locMessage, distance = os.pullEvent()
  570.     event, message = locEvent, locMessage
  571.   until (event == "timer" and idCheck == id) or (event == "modem_message" and confirm == channels.receive)
  572.   if event == "modem_message" then connected = true else connected = false end
  573.   message = message or ""
  574.   message = message:lower()
  575.   if message == "stop" then error("Rednet said to stop...",0) end
  576.   if message == "return" then
  577.     endingProcedure()
  578.     error('Rednet said go back to start...',0)
  579.   end
  580.   if message == "drop" then
  581.     dropOff()
  582.   end
  583. end
  584. --Showing changes to settings
  585. screen(1,1)
  586. print("Your selected settings:")
  587. if #changedT == 0 then
  588. print("Completely Default")
  589. else
  590. for i=1, #changedT do
  591. print(changedT[i][1],": ",changedT[i][2]) --Name and Value
  592. end
  593. end
  594. print("\nStarting in 3"); sleep(1); print("2"); sleep(1); print("1"); sleep(1.5) --Dramatic pause at end
  595.  
  596.  
  597.  
  598. ----------------------------------------------------------------
  599. --Define ALL THE FUNCTIONS
  600. function eventAdd(...)
  601.   return table.insert(events,1, {...}) or true
  602. end
  603. function eventGet(pos)
  604.   return events[tonumber(pos) or #events]
  605. end
  606. function eventPop(pos)
  607.   return table.remove(events,tonumber(pos) or #events) or false --This will return value popped, tonumber returns nil if fail, so default to end
  608. end
  609. function eventRun(value, ...)
  610.   local argsList = {...}
  611.   if type(value) == "string" then
  612.     if value:sub(-1) ~= ")" then --So supports both "up()" and "up"
  613.       value = value .. "("
  614.       for a, b in pairs(argsList) do --Appending arguments
  615.         local toAppend
  616.         if type(b) == "table" then toAppend = textutils.serialize(b)
  617.         elseif type(b) == "string" then toAppend = "\""..tostring(b).."\"" --They weren't getting strings around them
  618.         else toAppend = tostring(b) end
  619.         value = value .. (toAppend or "true") .. ", "
  620.       end
  621.       if value:sub(-1) ~= "(" then --If no args, do not want to cut off
  622.         value = value:sub(1,-3)..""
  623.       end
  624.       value = value .. ")"
  625.     end
  626.     --print(value) --Debug
  627.     local func = loadstring(value)
  628.     setfenv(func, getfenv(1))
  629.     return func()
  630.   end
  631. end
  632.      
  633. function runAllEvents()
  634.   while #events > 0 do
  635.     local toRun = eventGet()
  636.     --print(toRun[1]) --Debug
  637.     eventRun(unpack(toRun))
  638.     eventPop()
  639.   end
  640. end
  641.  
  642. function display() --This is just the last screen that displays at the end
  643.   screen(1,1)
  644.   print("Total Blocks Mined: "..mined)
  645.   print("Current Fuel Level: "..turtle.getFuelLevel())
  646.   print("Cobble: "..totals.cobble)
  647.   print("Usable Fuel: "..totals.fuel)
  648.   print("Other: "..totals.other)
  649.   if rednetEnabled then
  650.     print("")
  651.     print("Sent Stop Message")
  652.     local finalTable = {mined = mined, cobble = totals.cobble, fuelblocks = totals.fuel,
  653.         other = totals.other, fuel = checkFuel() }
  654.     modem.transmit(channels.send,channels.receive,"stop")
  655.     sleep(0.5)
  656.     modem.transmit(channels.send,channels.receive,textutils.serialize(finalTable))
  657.     modem.close(channels.receive)
  658.   end
  659.   if doBackup then fs.delete(saveFile) end
  660. end
  661. function updateDisplay() --Runs in Mine(), display information to the screen in a certain place
  662. screen(1,1)
  663. print("Blocks Mined")
  664. print(mined)
  665. print("Percent Complete")
  666. print(percent.."%")
  667. print("Fuel")
  668. print(checkFuel())
  669.   -- screen(1,1)
  670.   -- print("Xpos: ")
  671.   -- print(xPos)
  672.   -- print("RelXPos: ")
  673.   -- print(relxPos)
  674.   -- print("Z Pos: ")
  675.   -- print(zPos)
  676.   -- print("Y pos: ")
  677.   -- print(yPos)
  678. if rednetEnabled then
  679. screenLine(1,7)
  680. print("Connected: "..tostring(connected))
  681. end
  682. end
  683. function logMiningRun(textExtension, extras) --Logging mining runs
  684. if logging then
  685. local number
  686. if not fs.isDir(logFolder) then
  687.   fs.delete(logFolder)
  688.   fs.makeDir(logFolder)
  689.   number = 1
  690. else
  691.   local i = 0
  692.   repeat
  693.     i = i + 1
  694.   until not fs.exists(logFolder.."/Quarry_Log_"..tostring(i)..(textExtension or ""))
  695.   number = i
  696. end
  697. handle = fs.open(logFolder.."/Quarry_Log_"..tostring(number)..(textExtension or ""),"w")
  698. local function write(...)
  699.   for a, b in ipairs({...}) do
  700.     handle.write(tostring(b))
  701.   end
  702.   handle.write("\n")
  703. end
  704. write("Welcome to the Quarry Logs!")
  705. write("Entry Number: ",number)
  706. write("Dimensions (X Z Y): ",x," ",z," ", y)
  707. write("Blocks Mined: ", mined)
  708. write("  Cobble: ", totals.cobble)
  709. write("  Usable Fuel: ", totals.fuel)
  710. write("  Other: ",totals.other)
  711. write("Total Fuel Used: ",  (originalFuel or (neededFuel + checkFuel()))- checkFuel()) --Protect against errors with some precision
  712. write("Expected Fuel Use: ", neededFuel)
  713. handle.close()
  714. end
  715. end
  716. function isFull(slots)
  717.   slots = slots or 16
  718.   local numUsed = 0
  719.   sleep(0)
  720.   for i=1, 16 do
  721.     if turtle.getItemCount(i) > 0 then numUsed = numUsed + 1 end
  722.   end
  723.   if numUsed > slots then
  724.     return true
  725.   end
  726.   return false
  727. end
  728. function dig(doAdd, func)
  729.   doAdd = doAdd or true
  730.   func = func or turtle.dig
  731.   if func() then
  732.     if doAdd then
  733.       mined = mined + 1
  734.     end
  735.     return true
  736.   end
  737.   return false
  738. end
  739. if not inverted then --Regular functions :) I switch definitions for optimizatoin (I thinK)
  740.   function digUp(doAdd)
  741.     return dig(doAdd,turtle.digUp)
  742.   end
  743.   function digDown(doAdd)
  744.     return dig(doAdd,turtle.digDown)
  745.   end
  746. else
  747.   function digDown(doAdd)
  748.     return dig(doAdd,turtle.digUp)
  749.   end
  750.   function digUp(doAdd)
  751.     return dig(doAdd,turtle.digDown)
  752.   end
  753. end
  754. function relativeXCalc()
  755.   if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end
  756. end
  757. function forward(doAdd)
  758.   if doAdd == nil then doAdd = true end
  759.   if turtle.forward() then
  760.     if doAdd then
  761.       moved = moved + 1
  762.     end
  763.     if facing == 0 then
  764.       xPos = xPos + 1
  765.     elseif facing == 1 then
  766.       zPos = zPos + 1
  767.     elseif facing == 2 then
  768.       xPos = xPos - 1
  769.     elseif facing == 3 then
  770.       zPos = zPos - 1
  771.     else
  772.       error("Function forward, facing should be 0 - 3, got "..tostring(facing),2)
  773.     end
  774.     relativeXCalc()
  775.     return true
  776.   end
  777.   return false
  778. end
  779. function up(sneak)
  780.   sneak = sneak or 1
  781.   if inverted and sneak == 1 then
  782.     down(-1)
  783.   else
  784.     while not turtle.up() do --Absolute dig, not relative
  785.       if not dig(true, turtle.digUp) then
  786.         attackUp()
  787.         sleep(0.5)
  788.       end
  789.     end
  790.     yPos = yPos - sneak --Oh! I feel so clever
  791.   end                   --This works because inverted :)
  792.   saveProgress()
  793.   if rednetEnabled then biometrics() end
  794. end
  795. function down(sneak)
  796.   sneak = sneak or 1
  797.   local count = 0
  798.   if inverted and sneak == 1 then
  799.     up(-1)
  800.   else
  801.     while not turtle.down() do
  802.       count = count + 1
  803.       if not dig(true, turtle.digDown) then --This is absolute dig down, not relative
  804.         attackDown()
  805.         sleep(0.2)
  806.       end
  807.       if count > 20 then bedrock() end
  808.     end
  809.     yPos = yPos + sneak
  810.   end
  811.   saveProgress()
  812.   if rednetEnabled then biometrics() end
  813. end
  814. function right(num)
  815.   num = num or 1
  816.   for i=1, num do facing = coterminal(facing+1); saveProgress(); turtle.turnRight() end
  817. end
  818. function left(num)
  819.   num = num or 1
  820.   for i=1, num do facing = coterminal(facing-1); saveProgress(); turtle.turnLeft() end
  821. end
  822. function attack(doAdd, func)
  823.   doAdd = doAdd or true
  824.   func = func or turtle.attack
  825.   if func() then
  826.     if doAdd then
  827.       attacked = attacked + 1
  828.     end
  829.     return true
  830.   end
  831.   return false
  832. end
  833. function attackUp(doAdd)
  834.   if inverted then
  835.     return attack(doAdd, turtle.attackDown)
  836.   else
  837.     return attack(doAdd, turtle.attackUp)
  838.   end
  839. end
  840. function attackDown(doAdd)
  841.   if inverted then
  842.     return attack(doAdd, turtle.attackUp)
  843.   else
  844.     return attack(doAdd, turtle.attackDown)
  845.   end
  846. end
  847.  
  848.  
  849. function mine(doDigDown, doDigUp, outOfPath,doCheckInv) -- Basic Move Forward
  850.   if doCheckInv == nil then doCheckInv = true end
  851.   if doDigDown == nil then doDigDown = true end
  852.   if doDigUp == nil then doDigUp = true end
  853.   if outOfPath == nil then outOfPath = false end
  854.   if inverted then
  855.     doDigUp, doDigDown = doDigDown, doDigUp --Just Switch the two if inverted
  856.   end
  857.   if doRefuel and checkFuel() <= fuelTable[fuelSafety]/2 then
  858.     for i=1, 16 do
  859.     if turtle.getItemCount(i) > 0 then
  860.       turtle.select(i)
  861.       if checkFuel() < 200 + fuelTable[fuelSafety] then
  862.         turtle.refuel()
  863.       end
  864.     end
  865.     end
  866.     turtle.select(1)
  867.   end
  868.   local count = 0
  869.   while not forward(not outOfPath) do
  870.     sleep(0) --Calls coroutine.yield to prevent errors
  871.     count = count + 1
  872.     if not dig() then
  873.       attack()
  874.     end
  875.     if count > 10 then
  876.       attack()
  877.       sleep(0.2)
  878.     end
  879.     if count > maxTries then
  880.       if turtle.getFuelLevel() == 0 then --Don't worry about inf fuel because I modified this function
  881.         saveProgress({doCheckFuel = true})
  882.         error("No more fuel",0)
  883.       elseif yPos > (startY-7) and turtle.detect() then --If it is near bedrock
  884.         bedrock()
  885.       else --Otherwise just sleep for a bit to avoid sheeps
  886.         sleep(1)
  887.       end
  888.     end
  889.   end
  890.   checkSanity() --Not kidding... This is necessary
  891.   saveProgress(tab)
  892.   if doDigUp and (not hack or (hack and not turtle.compareUp())) then
  893.   while turtle.detectUp() do
  894.     sleep(0) --Calls coroutine.yield
  895.     if not dig(true,turtle.digUp) then --This needs to be an absolute, because we are switching doDigUp/Down
  896.       attackUp()
  897.       count = count + 1
  898.     end
  899.     if count > 50 and yPos > (startY-7) then --Same deal with bedrock as above
  900.       bedrock()
  901.     end
  902.     end
  903.   end
  904.   if doDigDown and (not hack or (hack and not turtle.compareDown())) then
  905.    dig(true,turtle.digDown) --This needs to be absolute as well
  906.   end
  907.   percent = math.ceil(moved/moveVolume*100)
  908.   updateDisplay()
  909.   isInPath = (not outOfPath) --For rednet
  910.   if doCheckInv and careAboutResources then
  911.     if moved%invCheckFreq == 0 then
  912.      if isFull(16-keepOpen) then dropOff() end
  913.     end
  914.   end
  915.   if rednetEnabled then biometrics() end
  916. end
  917. --Insanity Checking
  918. function checkSanity()
  919.   if isInPath and not (facing == 0 or facing == 2) and #events == 0 then --If mining and not facing proper direction and not in a turn
  920.     turnTo(0)
  921.     rowCheck = "right"
  922.   end
  923.   if xPos < 0 or xPos > x or zPos < 0 or zPos > z or yPos < 0 then
  924.     saveProgress()
  925.     print("Oops. Detected that quarry was outside of predefined boundaries.")
  926.     print("Please go to my forum thread and report this with a short description of what happened")
  927.     print("If you could also run \"pastebin put Civil_Quarry_Restore\" and give me that code it would be great")
  928.     error("",0)
  929.   end
  930. end
  931.  
  932. local function fromBoolean(input) --Like a calculator
  933. if input then return 1 end
  934. return 0
  935. end
  936. local function multBoolean(first,second) --Boolean multiplication
  937. return (fromBoolean(first) * fromBoolean(second)) == 1
  938. end
  939. function coterminal(num, limit) --I knew this would come in handy :D
  940. limit = limit or 4 --This is for facing
  941. return math.abs((limit*fromBoolean(num < 0))-(math.abs(num)%limit))
  942. end
  943. if tArgs["-manualpos"] then
  944.   facing = coterminal(facing) --Done to improve support for "-manualPos"
  945.   if facing == 0 then rowCheck = "right" elseif facing == 2 then rowCheck = "left" end --Ditto
  946.   relativeXCalc() --Ditto
  947. end
  948.  
  949. --Direction: Front = 0, Right = 1, Back = 2, Left = 3
  950.  
  951. function turnTo(num)
  952.   num = num or facing
  953.   num = coterminal(num) --Prevent errors
  954.   local turnRight = true
  955.   if facing-num == 1 or facing-num == -3 then turnRight = false end --0 - 1 = -3, 1 - 0 = 1, 2 - 1 = 1
  956.   while facing ~= num do          --The above is used to smartly turn
  957.     if turnRight then
  958.       right()
  959.     else
  960.       left()
  961.     end
  962.   end
  963. end
  964. function goto(x,z,y, toFace, destination)
  965.   --Will first go to desired z pos, then x pos, y pos varies
  966.   x = x or 1; y = y or 1; z = z or 1; toFace = toFace or facing
  967.   gotoDest = destination or "" --This is used by biometrics
  968.   --Possible destinations: layerStart, quarryStart
  969.   if yPos > y then --Will go up first if below position
  970.     while yPos~=y do up() end
  971.   end
  972.   if zPos > z then
  973.     turnTo(3)
  974.   elseif zPos < z then
  975.     turnTo(1)
  976.   end
  977.   while zPos ~= z do mine(false,false,true,false) end
  978.   if xPos > x then
  979.     turnTo(2)
  980.   elseif xPos < x then
  981.     turnTo(0)
  982.   end
  983.   while xPos ~= x do mine(false,false,true,false) end
  984.   if yPos < y then --Will go down after if above position
  985.     while yPos~=y do down() end
  986.   end
  987.   turnTo(toFace)
  988.   saveProgress()
  989.   gotoDest = ""
  990. end
  991. function getNumOpenSlots()
  992.   local toRet = 0
  993.   for i=1, 16 do
  994.     if turtle.getItemCount(i) == 0 then
  995.       toRet = toRet + 1
  996.     end
  997.   end
  998.   return toRet
  999. end
  1000. function drop(side, final, allowSkip)
  1001. side = sides[side] or "front"    --The final number means that it will
  1002. if final then final = 0 else final = 1 end --drop a whole stack at the end
  1003. local allowSkip = allowSkip or (final == 0) --This will allow drop(side,t/f, rednetConnected)
  1004. count()
  1005. if doRefuel then
  1006.   for i=1, 16 do
  1007.     if slot[i][1] == 2 then
  1008.       turtle.select(i); turtle.refuel()
  1009.     end
  1010.   end
  1011.   turtle.select(1)
  1012. end
  1013. if side == "right" then turnTo(1) end
  1014. if side == "left" then turnTo(3) end
  1015. local whereDetect, whereDrop1, whereDropAll
  1016. local _1 = slot[1][2] - final --All but one if final, all if not final
  1017. if side == "top" then
  1018. whereDetect = turtle.detectUp ; whereDrop = turtle.dropUp
  1019. elseif side == "bottom" then
  1020. whereDetect = turtle.detectDown ; whereDrop = turtle.dropDown
  1021. else
  1022. whereDetect = turtle.detect; whereDrop = turtle.drop
  1023. end
  1024. local function waitDrop(val) --This will just drop, but wait if it can't
  1025.   val = val or 64
  1026.   local try = 1
  1027.   while not whereDrop(val) do
  1028.     print("Chest Full, Try "..try)
  1029.     chestFull = true
  1030.     if rednetEnabled then --To send that the chest is full
  1031.       biometrics()
  1032.     end
  1033.     try = try + 1
  1034.     sleep(2)
  1035.   end
  1036.   chestFull = false
  1037. end
  1038. repeat
  1039. local detected = whereDetect()
  1040. if detected then
  1041.   waitDrop(_1)
  1042.   for i=1, 2 do --This is so I quit flipping missing items when chests are partially filled
  1043.     for i=2, 16 do
  1044.       if turtle.getItemCount(i) > 0 then
  1045.         turtle.select(i)
  1046.         waitDrop(nil, i)
  1047.       end
  1048.     end
  1049.   end
  1050. elseif not allowSkip then
  1051.   print("Waiting for chest placement place a chest to continue")
  1052.   while not whereDetect() do
  1053.     sleep(1)
  1054.   end
  1055. end
  1056. until detected or allowSkip
  1057. if not allowSkip then totals.cobble = totals.cobble - 1 end
  1058. turtle.select(1)
  1059. end
  1060. function dropOff() --Not local because called in mine()
  1061.   local currX,currZ,currY,currFacing = xPos, zPos, yPos, facing
  1062.   if careAboutResources then
  1063.     if not enderChestEnabled then --Regularly
  1064.       eventAdd("goto", 1,1,currY,2) --Need this step for "-startDown"
  1065.       eventAdd("goto(0,1,1,2)")
  1066.       eventAdd("drop", dropSide,false)
  1067.       eventAdd("turnTo(0)")
  1068.       eventAdd("mine",false,false,true,false)
  1069.       eventAdd("goto(1,1,1, 0)")
  1070.       eventAdd("goto", 1, 1, currY, 0)
  1071.       eventAdd("goto", currX,currZ,currY,currFacing)
  1072.     else --If using an enderChest
  1073.       eventAdd("turnTo",currFacing-2)
  1074.       eventAdd("dig",false)
  1075.       eventAdd("turtle.select",enderChestSlot)
  1076.       eventAdd("turtle.place")
  1077.       eventAdd("drop","front",false)
  1078.       eventAdd("turtle.select", enderChestSlot)
  1079.       eventAdd("dig",false)
  1080.       eventAdd("turnTo",currFacing)
  1081.       eventAdd("turtle.select(1)")
  1082.     end
  1083.   runAllEvents()
  1084.   end
  1085. return true
  1086. end
  1087. function endingProcedure() --Used both at the end and in "biometrics"
  1088.   eventAdd("goto",1,1,yPos,2,"quarryStart") --Allows for startDown variable
  1089.   eventAdd("goto",0,1,1,2, "quarryStart") --Go back to base
  1090.   runAllEvents()
  1091.   --Output to a chest or sit there
  1092.   if enderChestEnabled then
  1093.     while turtle.detect() do dig(false) end --This gets rid of blocks in front of the turtle.
  1094.     eventAdd("turtle.select",enderChestSlot)
  1095.     eventAdd("turtle.place")
  1096.     eventAdd("turtle.select(1)")
  1097.   end
  1098.   eventAdd("drop",dropSide, true)
  1099.   eventAdd("turnTo(0)")
  1100.  
  1101.   --Display was moved above to be used in bedrock function
  1102.   eventAdd("display")
  1103.   --Log current mining run
  1104.   eventAdd("logMiningRun",logExtension)
  1105.   toQuit = true --I'll use this flag to clean up
  1106.   runAllEvents()
  1107.   --Cleanup
  1108.   turtle.getFuelLevel = getFuel
  1109. end
  1110. function bedrock()
  1111. foundBedrock = true --Let everyone know
  1112. if rednetEnabled then biometrics() end
  1113. if checkFuel() == 0 then error("No Fuel",0) end
  1114. local origin = {x = xPos, y = yPos, z = zPos}
  1115. print("Bedrock Detected")
  1116. if turtle.detectUp() then
  1117. print("Block Above")
  1118. local var
  1119. if facing == 0 then var = 2 elseif facing == 2 then var = 0 else error("Was facing left or right on bedrock") end
  1120. goto(xPos,zPos,yPos,var)
  1121. for i=1, relxPos do mine(true,true); end
  1122. end
  1123. endingProcedure()
  1124. print("\nFound bedrock at these coordinates: ")
  1125. print(origin.x," Was position in row\n",origin.z," Was row in layer\n",origin.y," Blocks down from start")
  1126. error("",0)
  1127. end
  1128.  
  1129. function endOfRowTurn(startZ, wasFacing, mineFunctionTable)
  1130. local halfFacing = 1
  1131. local toFace = coterminal(wasFacing + 2) --Opposite side
  1132. if zPos == startZ then
  1133.   if facing ~= halfFacing then turnTo(halfFacing) end
  1134.   mine(unpack(mineFunctionTable or {}))
  1135. end
  1136. if facing ~= toFace then
  1137.   turnTo(toFace)
  1138. end
  1139. end
  1140.  
  1141. -------------------------------------------------------------------------------------
  1142. --Pre-Mining Stuff dealing with session persistence
  1143. runAllEvents()
  1144. if toQuit then error("",0) end --This means that it was stopped coming for its last drop
  1145.  
  1146. local doDigDown, doDigUp = (lastHeight ~= 1), (lastHeight == 0) --Used in lastHeight
  1147. if not restoreFoundSwitch then --Regularly
  1148.   --Check if it is a mining turtle
  1149.   if not isMiningTurtle then
  1150.     local a, b = turtle.dig()
  1151.     if a then mined = mined + 1; isMiningTurtle = true
  1152.     elseif b == "Nothing to dig with" then
  1153.       print("This is not a mining turtle. To make a mining turtle, craft me together with a diamond pickaxe")
  1154.       error("",0)
  1155.     end
  1156.   end
  1157.   mine(false,false,true) --Get into quarry by going forward one
  1158.   if gpsEnabled and not restoreFoundSwitch then --The initial locate is done in the arguments. This is so I can figure out what quadrant the turtle is in.
  1159.   gpsSecondPos = {gps.locate(gpsTimeout)} --Note: Does not run this if it has already been restarted.
  1160. end
  1161.   for i = 1, startDown do
  1162.     eventAdd("down") --Add a bunch of down events to get to where it needs to be.
  1163.   end
  1164.   runAllEvents()
  1165.   if not(y == 1 or y == 2) then down() end --Go down. If y is one or two, it doesn't need to do this.
  1166. else --restore found
  1167.   if doDigDown then digDown() end
  1168.   if doDigUp then digUp() end  --Get blocks missed before stopped
  1169. end
  1170. --Mining Loops--------------------------------------------------------------------------
  1171. turtle.select(1)
  1172. while layersDone <= layers do -------------Height---------
  1173. local lastLayer = layersDone == layers --If this is the last layer
  1174. local secondToLastLayer = (layersDone + 1) == layers --This is for the going down at the end of a layer.
  1175. moved = moved + 1 --To account for the first position in row as "moved"
  1176. if doDigDown then digDown() end --This is because it doesn't mine first block in layer
  1177. if not restoreFoundSwitch then rowCheck = "right" end
  1178. relativeXCalc()
  1179. while zPos <= z do -------------Width----------
  1180. while relxPos < x do ------------Length---------
  1181. mine(not lastLayer or (doDigDown and lastLayer), not lastLayer or (doDigUp and lastLayer)) --This will be the idiom that I use for the mine function
  1182. end ---------------Length End-------
  1183. if zPos ~= z then --If not on last row of section
  1184.   local func
  1185.   if rowCheck == "right" then --Swithcing to next row
  1186.   func = "right"; rowCheck = "left"; else func = "left"; rowCheck = "right" end --Which way to turn
  1187.     eventAdd("endOfRowTurn", zPos, facing , {not lastLayer or (doDigDown and lastLayer), not lastLayer or (doDigUp and lastLayer)}) --The table is passed to the mine function
  1188.     runAllEvents()
  1189. else break
  1190. end
  1191. end ---------------Width End--------
  1192. eventAdd("goto",1,1,yPos,0, "layerStart") --Goto start of layer
  1193. runAllEvents()
  1194. if not lastLayer then --If there is another layer
  1195.   for i=1, 2+fromBoolean(not(lastHeight~=0 and secondToLastLayer)) do down() end --The fromBoolean stuff means that if lastheight is 1 and last and layer, will only go down two
  1196. end
  1197. layersDone = layersDone + 1
  1198. restoreFoundSwitch = false --This is done so that rowCheck works properly upon restore
  1199. end ---------------Height End-------
  1200.  
  1201. endingProcedure() --This takes care of getting to start, dropping in chest, and displaying ending screen
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement